From 74fd7c491ff74d32f94ca02a50c956ae205278dc Mon Sep 17 00:00:00 2001
From: Nicole Collings <100Toby1@gmail.com>
Date: Mon, 20 Apr 2020 14:20:15 -0700
Subject: [PATCH] New chunk-based rendering method, reorganized file structure

---
 src/{data => Data}/TILESETS.ts                |    0
 src/{data => Data}/TOKENS.ts                  |    0
 src/LoadScene.ts                              |    2 +-
 src/MapScene/FogOfWar.ts                      |   79 +
 .../History}/HistoryElement.ts                |    4 +-
 .../History}/HistoryManager.ts                |    0
 .../interface => MapScene/Interface}/Chat.ts  |    0
 .../Interface}/Chatbox.ts                     |    0
 .../Interface/Components}/UIComponent.ts      |    0
 .../Interface/Components}/UIContainer.ts      |    0
 .../Components}/UIHistoryManipulation.ts      |    0
 .../Components}/UIModeSwitchButton.ts         |    0
 .../Interface/Components}/UISideMenuButton.ts |    0
 .../Interface/Components}/UISidebar.ts        |    0
 .../Interface/Components}/UISidebarToggle.ts  |    0
 .../Interface/Components}/UITileSelector.ts   |    0
 .../Interface/Components}/UITileSidebar.ts    |    6 +-
 .../Interface/Components}/UITokenProps.ts     |    0
 .../Interface/Components}/UITokenSelector.ts  |    0
 .../Interface/Components}/UITokenSidebar.ts   |    0
 .../Interface/Modes}/ArchitectMode.ts         |   10 +-
 .../Interface/Modes}/TokenMode.ts             |    0
 .../Interface}/TextInput.ts                   |    0
 .../Interface}/UIView.ts                      |   19 +
 src/MapScene/Lighting/Lighting.ts             |    9 +
 src/MapScene/Map/MapChunk.ts                  |   90 +
 src/MapScene/Map/MapData.ts                   |  138 +
 .../tile => MapScene/Map}/SmartTiler.ts       |    2 +-
 src/MapScene/Map/TilesetManager.ts            |   31 +
 src/MapScene/MapScene.ts                      |   58 +
 src/{map_scene => MapScene}/Token.ts          |    0
 src/{map_scene => MapScene}/WorldView.ts      |    0
 src/{shader => Shaders}/BrightenPipeline.ts   |    0
 src/{shader => Shaders}/OutlinePipeline.ts    |    0
 src/{util => Util}/InputManager.ts            |    0
 src/{util => Util}/Util.ts                    |    0
 src/{util => Util}/Vector.ts                  |   12 +
 src/map_scene/FogOfWar.ts                     |   79 -
 src/map_scene/MapScene.ts                     |   76 -
 src/map_scene/tile/Tilemap.ts                 |  183 --
 src/map_scene/tile/TilesetCanvas.ts           |  108 -
 src/map_scene/tile/TilesetManager.ts          |   65 -
 tool.js                                       | 2350 ++++++++---------
 tsconfig.json                                 |    3 +-
 44 files changed, 1603 insertions(+), 1721 deletions(-)
 rename src/{data => Data}/TILESETS.ts (100%)
 rename src/{data => Data}/TOKENS.ts (100%)
 create mode 100644 src/MapScene/FogOfWar.ts
 rename src/{map_scene/history => MapScene/History}/HistoryElement.ts (95%)
 rename src/{map_scene/history => MapScene/History}/HistoryManager.ts (100%)
 rename src/{map_scene/interface => MapScene/Interface}/Chat.ts (100%)
 rename src/{map_scene/interface => MapScene/Interface}/Chatbox.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UIComponent.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UIContainer.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UIHistoryManipulation.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UIModeSwitchButton.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UISideMenuButton.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UISidebar.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UISidebarToggle.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UITileSelector.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UITileSidebar.ts (95%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UITokenProps.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UITokenSelector.ts (100%)
 rename src/{map_scene/interface/components => MapScene/Interface/Components}/UITokenSidebar.ts (100%)
 rename src/{map_scene/modes => MapScene/Interface/Modes}/ArchitectMode.ts (95%)
 rename src/{map_scene/modes => MapScene/Interface/Modes}/TokenMode.ts (100%)
 rename src/{map_scene/interface => MapScene/Interface}/TextInput.ts (100%)
 rename src/{map_scene/interface => MapScene/Interface}/UIView.ts (88%)
 create mode 100644 src/MapScene/Lighting/Lighting.ts
 create mode 100644 src/MapScene/Map/MapChunk.ts
 create mode 100644 src/MapScene/Map/MapData.ts
 rename src/{map_scene/tile => MapScene/Map}/SmartTiler.ts (98%)
 create mode 100644 src/MapScene/Map/TilesetManager.ts
 create mode 100644 src/MapScene/MapScene.ts
 rename src/{map_scene => MapScene}/Token.ts (100%)
 rename src/{map_scene => MapScene}/WorldView.ts (100%)
 rename src/{shader => Shaders}/BrightenPipeline.ts (100%)
 rename src/{shader => Shaders}/OutlinePipeline.ts (100%)
 rename src/{util => Util}/InputManager.ts (100%)
 rename src/{util => Util}/Util.ts (100%)
 rename src/{util => Util}/Vector.ts (85%)
 delete mode 100644 src/map_scene/FogOfWar.ts
 delete mode 100644 src/map_scene/MapScene.ts
 delete mode 100644 src/map_scene/tile/Tilemap.ts
 delete mode 100644 src/map_scene/tile/TilesetCanvas.ts
 delete mode 100644 src/map_scene/tile/TilesetManager.ts

diff --git a/src/data/TILESETS.ts b/src/Data/TILESETS.ts
similarity index 100%
rename from src/data/TILESETS.ts
rename to src/Data/TILESETS.ts
diff --git a/src/data/TOKENS.ts b/src/Data/TOKENS.ts
similarity index 100%
rename from src/data/TOKENS.ts
rename to src/Data/TOKENS.ts
diff --git a/src/LoadScene.ts b/src/LoadScene.ts
index b19d5d3..623c03b 100644
--- a/src/LoadScene.ts
+++ b/src/LoadScene.ts
@@ -105,7 +105,7 @@ class LoadScene extends Phaser.Scene {
 				this.patching = this.add.sprite(this.cameras.main.width / 2, this.cameras.main.height / 2 - 100, "loader_patching");
 				this.patching.setScale(6);
 
-				this.text.setText(" Patching Tiles...");	
+				this.text.setText(" Loading Map...");	
 		
 				setTimeout(() => {
 					this.game.scene.start('MapScene');
diff --git a/src/MapScene/FogOfWar.ts b/src/MapScene/FogOfWar.ts
new file mode 100644
index 0000000..b27ceec
--- /dev/null
+++ b/src/MapScene/FogOfWar.ts
@@ -0,0 +1,79 @@
+// class FogOfWar {
+// 	scene: MapScene;
+
+// 	tex: Phaser.GameObjects.RenderTexture;
+// 	map: Phaser.Tilemaps.Tilemap;
+// 	historyLayer: Phaser.Tilemaps.DynamicTilemapLayer;
+	
+// 	dims: Vec2;
+
+// 	constructor(scene: MapScene, dims: Vec2) {
+// 		this.scene = scene;
+// 		this.dims = dims;
+
+// 		this.tex = new Phaser.GameObjects.RenderTexture(this.scene, 0, 0, this.dims.x*16, this.dims.y*16);
+// 		this.tex.setScale(4, 4);
+// 		this.tex.setAlpha(0.7);
+// 		this.scene.add.existing(this.tex);
+
+// 		// this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
+// 		// this.map.addTilesetImage("history", "wall_shadow", 16, 16, 0, 0);
+// 		// this.map.setLayer("history");
+// 		// this.historyLayer = this.map.createBlankDynamicLayer("history", "wall_shadow", 0, 0, this.dims.x, this.dims.y, 16, 16);
+// 		// this.historyLayer.setScale(4, 4);
+
+// 		// for (let i = 0; i < this.dims.x; i++) {
+// 		// 	for (let j = 0; j < this.dims.y; j++) {
+// 		// 		if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) this.historyLayer.putTileAt(0, i, j);
+// 		// 	}
+// 		// }
+
+// 	}
+
+// 	update() {
+// 		let resetSquare = new Phaser.GameObjects.Rectangle(this.scene, 0, 0, this.dims.x*16, this.dims.y*16, 0x000000);
+// 		this.tex.draw(resetSquare);
+
+// 		for (let token of this.scene.tokens) {
+// 			let startTile = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64))
+
+// 			let points: Vec2[] = [];
+
+// 			for (let i = 0; i < 288; i++) {
+// 				let ray = new Vec2(0.5, 0.5);
+// 				let dir = new Vec2(Math.cos(i * 1.25 * (Math.PI / 180)) / 32, Math.sin(i * 1.25 * (Math.PI / 180)) / 32);
+
+// 				let dist = 0;
+// 				let maxDist = 12;
+
+// 				while (this.scene.map.getWall(Math.floor(startTile.x + ray.x), Math.floor(startTile.y + ray.y)) == -1 && 
+// 					(dist = Math.sqrt(Math.pow(ray.x, 2) + Math.pow(ray.y, 2))) < maxDist) {
+// 					ray.x += dir.x;
+// 					ray.y += dir.y;
+// 				}
+
+// 				ray.x -= dir.x * maxDist * 2.4;
+// 				ray.y -= dir.y * maxDist * 2.4;
+
+// 				ray.x += dir.x * ((maxDist - dist) * 2.8);
+// 				ray.y += dir.y * ((maxDist - dist) * 2.8);
+
+// 				points.push(new Vec2(ray.x * 4, ray.y * 4));
+// 			}
+
+// 			let poly = new Phaser.GameObjects.Polygon(this.scene, token.x / 4, token.y / 4, points, 0xffffff, 0.4);
+// 			poly.setScale(4, 4);
+// 			poly.setBlendMode('ERASE');
+// 			poly.setDisplayOrigin(0, 0);
+// 			poly.setOrigin(0, 0);
+
+// 			for (let i = 0; i < 10; i++) {
+// 				poly.scaleX += 0.04;
+// 				poly.scaleY += 0.04;
+// 				// poly.x = token.x / 4 + 50 * poly.scaleX;
+// 				// poly.y = token.y / 4 + 50 * poly.scaleY;
+// 				this.tex.draw(poly);
+// 			}
+// 		}
+// 	}
+// }
diff --git a/src/map_scene/history/HistoryElement.ts b/src/MapScene/History/HistoryElement.ts
similarity index 95%
rename from src/map_scene/history/HistoryElement.ts
rename to src/MapScene/History/HistoryElement.ts
index 52decbd..e1df4e5 100644
--- a/src/map_scene/history/HistoryElement.ts
+++ b/src/MapScene/History/HistoryElement.ts
@@ -13,7 +13,7 @@ class HistoryElement {
 		console.log("Undo", this.type);
 		if (this.type == "tile") {
 			for (let tile of this.data as {pos: Vec2, layer: Layer, lastTile: number, tile: number}[])
-				this.scene.map.setTile(tile.pos.x, tile.pos.y, tile.lastTile, tile.layer);
+				this.scene.map.setTile(tile.layer, tile.lastTile, tile.pos.x, tile.pos.y);
 		}
 		else if (this.type == "token_modify") {
 			let data = this.data as { old: string[], new: string[] };
@@ -61,7 +61,7 @@ class HistoryElement {
 		console.log("Redo", this.type);
 		if (this.type == "tile") {
 			for (let tile of this.data as {pos: Vec2, layer: Layer, lastTile: number, tile: number}[])
-				this.scene.map.setTile(tile.pos.x, tile.pos.y, tile.tile, tile.layer);
+				this.scene.map.setTile(tile.layer, tile.tile, tile.pos.x, tile.pos.y);
 		}
 		else if (this.type == "token_modify") {
 			let data = this.data as { old: string[], new: string[] };
diff --git a/src/map_scene/history/HistoryManager.ts b/src/MapScene/History/HistoryManager.ts
similarity index 100%
rename from src/map_scene/history/HistoryManager.ts
rename to src/MapScene/History/HistoryManager.ts
diff --git a/src/map_scene/interface/Chat.ts b/src/MapScene/Interface/Chat.ts
similarity index 100%
rename from src/map_scene/interface/Chat.ts
rename to src/MapScene/Interface/Chat.ts
diff --git a/src/map_scene/interface/Chatbox.ts b/src/MapScene/Interface/Chatbox.ts
similarity index 100%
rename from src/map_scene/interface/Chatbox.ts
rename to src/MapScene/Interface/Chatbox.ts
diff --git a/src/map_scene/interface/components/UIComponent.ts b/src/MapScene/Interface/Components/UIComponent.ts
similarity index 100%
rename from src/map_scene/interface/components/UIComponent.ts
rename to src/MapScene/Interface/Components/UIComponent.ts
diff --git a/src/map_scene/interface/components/UIContainer.ts b/src/MapScene/Interface/Components/UIContainer.ts
similarity index 100%
rename from src/map_scene/interface/components/UIContainer.ts
rename to src/MapScene/Interface/Components/UIContainer.ts
diff --git a/src/map_scene/interface/components/UIHistoryManipulation.ts b/src/MapScene/Interface/Components/UIHistoryManipulation.ts
similarity index 100%
rename from src/map_scene/interface/components/UIHistoryManipulation.ts
rename to src/MapScene/Interface/Components/UIHistoryManipulation.ts
diff --git a/src/map_scene/interface/components/UIModeSwitchButton.ts b/src/MapScene/Interface/Components/UIModeSwitchButton.ts
similarity index 100%
rename from src/map_scene/interface/components/UIModeSwitchButton.ts
rename to src/MapScene/Interface/Components/UIModeSwitchButton.ts
diff --git a/src/map_scene/interface/components/UISideMenuButton.ts b/src/MapScene/Interface/Components/UISideMenuButton.ts
similarity index 100%
rename from src/map_scene/interface/components/UISideMenuButton.ts
rename to src/MapScene/Interface/Components/UISideMenuButton.ts
diff --git a/src/map_scene/interface/components/UISidebar.ts b/src/MapScene/Interface/Components/UISidebar.ts
similarity index 100%
rename from src/map_scene/interface/components/UISidebar.ts
rename to src/MapScene/Interface/Components/UISidebar.ts
diff --git a/src/map_scene/interface/components/UISidebarToggle.ts b/src/MapScene/Interface/Components/UISidebarToggle.ts
similarity index 100%
rename from src/map_scene/interface/components/UISidebarToggle.ts
rename to src/MapScene/Interface/Components/UISidebarToggle.ts
diff --git a/src/map_scene/interface/components/UITileSelector.ts b/src/MapScene/Interface/Components/UITileSelector.ts
similarity index 100%
rename from src/map_scene/interface/components/UITileSelector.ts
rename to src/MapScene/Interface/Components/UITileSelector.ts
diff --git a/src/map_scene/interface/components/UITileSidebar.ts b/src/MapScene/Interface/Components/UITileSidebar.ts
similarity index 95%
rename from src/map_scene/interface/components/UITileSidebar.ts
rename to src/MapScene/Interface/Components/UITileSidebar.ts
index f431286..63aa578 100644
--- a/src/map_scene/interface/components/UITileSidebar.ts
+++ b/src/MapScene/Interface/Components/UITileSidebar.ts
@@ -49,15 +49,15 @@ class UITileSidebar extends UISidebar {
 	elemClick(x: number, y: number): void {
 		if (y < 4) {
 			this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.walls[x + y * 3]];
-			this.scene.architect.activeLayer = Layer.WALL;
+			this.scene.architect.activeLayer = Layer.wall;
 		}
 		else if (y < 8) {
 			this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.grounds[x + (y - 4) * 3]];
-			this.scene.architect.activeLayer = Layer.GROUND;
+			this.scene.architect.activeLayer = Layer.floor;
 		}
 		else {
 			this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.overlays[x + (y - 8) * 3]];
-			this.scene.architect.activeLayer = Layer.OVERLAY;
+			this.scene.architect.activeLayer = Layer.overlay;
 		}
 	}
 
diff --git a/src/map_scene/interface/components/UITokenProps.ts b/src/MapScene/Interface/Components/UITokenProps.ts
similarity index 100%
rename from src/map_scene/interface/components/UITokenProps.ts
rename to src/MapScene/Interface/Components/UITokenProps.ts
diff --git a/src/map_scene/interface/components/UITokenSelector.ts b/src/MapScene/Interface/Components/UITokenSelector.ts
similarity index 100%
rename from src/map_scene/interface/components/UITokenSelector.ts
rename to src/MapScene/Interface/Components/UITokenSelector.ts
diff --git a/src/map_scene/interface/components/UITokenSidebar.ts b/src/MapScene/Interface/Components/UITokenSidebar.ts
similarity index 100%
rename from src/map_scene/interface/components/UITokenSidebar.ts
rename to src/MapScene/Interface/Components/UITokenSidebar.ts
diff --git a/src/map_scene/modes/ArchitectMode.ts b/src/MapScene/Interface/Modes/ArchitectMode.ts
similarity index 95%
rename from src/map_scene/modes/ArchitectMode.ts
rename to src/MapScene/Interface/Modes/ArchitectMode.ts
index e8998d1..94310e1 100644
--- a/src/map_scene/modes/ArchitectMode.ts
+++ b/src/MapScene/Interface/Modes/ArchitectMode.ts
@@ -11,7 +11,7 @@ class ArchitectMode {
 	pointerPrimaryDown: boolean = false;
 
 	activeTileset: number = 0;
-	activeLayer: Layer = Layer.WALL;
+	activeLayer: Layer = Layer.wall;
 
 	manipulated: {pos: Vec2, layer: Layer, lastTile: number, tile: number}[] = [];
 
@@ -33,7 +33,7 @@ class ArchitectMode {
 		this.cursor.setPosition(selectedTilePos.x * 64, selectedTilePos.y * 64);
 
 		this.cursor.setVisible((selectedTilePos.x >= 0 && selectedTilePos.y >= 0 && 
-			selectedTilePos.x < this.scene.map.dimensions.x && selectedTilePos.y < this.scene.map.dimensions.y));
+			selectedTilePos.x < this.scene.map.size.x && selectedTilePos.y < this.scene.map.size.y));
 
 		// Place Tiles
 		switch(this.placeMode) {
@@ -188,12 +188,12 @@ class ArchitectMode {
 
 	placeTileAndPushManip(manipPos: Vec2, solid: boolean) {
 		let tile = solid ? this.activeTileset : -1;
-		let layer = (tile == -1 && this.activeLayer == Layer.GROUND) ? Layer.WALL : this.activeLayer;
+		let layer = (tile == -1 && this.activeLayer == Layer.floor) ? Layer.wall : this.activeLayer;
 
-		let lastTile = this.scene.map.getTile(manipPos.x, manipPos.y, layer);
+		let lastTile = this.scene.map.getTileset(layer, manipPos.x, manipPos.y);
 		if (tile == lastTile) return;
 		
-		this.scene.map.setTile(manipPos.x, manipPos.y, tile, layer);
+		this.scene.map.setTile(layer, tile, manipPos.x, manipPos.y);
 
 		this.manipulated.push({
 			pos: manipPos, 
diff --git a/src/map_scene/modes/TokenMode.ts b/src/MapScene/Interface/Modes/TokenMode.ts
similarity index 100%
rename from src/map_scene/modes/TokenMode.ts
rename to src/MapScene/Interface/Modes/TokenMode.ts
diff --git a/src/map_scene/interface/TextInput.ts b/src/MapScene/Interface/TextInput.ts
similarity index 100%
rename from src/map_scene/interface/TextInput.ts
rename to src/MapScene/Interface/TextInput.ts
diff --git a/src/map_scene/interface/UIView.ts b/src/MapScene/Interface/UIView.ts
similarity index 88%
rename from src/map_scene/interface/UIView.ts
rename to src/MapScene/Interface/UIView.ts
index ba06deb..424b837 100644
--- a/src/map_scene/interface/UIView.ts
+++ b/src/MapScene/Interface/UIView.ts
@@ -19,6 +19,8 @@ class UIView {
 		this.camera.scrollX = -10000;
 
 		this.o = this.scene.add.container(-10000, 0);
+
+		this.createElements();
 	}
 
 	createElements() {
@@ -81,6 +83,23 @@ class UIView {
 				this.displayToken();
 			}
 		}
+
+		if (this.scene.i.keyPressed('TAB')) this.scene.mode = (this.scene.mode == 0 ? 1 : 0);
+
+		if (this.scene.mode == 0) {
+			if (this.uiActive) this.scene.architect.cleanup();
+			else {
+				this.scene.architect.update();
+				this.scene.token.cleanup();
+			}
+		}
+		else {
+			if (this.uiActive) this.scene.token.cleanup();
+			else {
+				this.scene.token.update();
+				this.scene.architect.cleanup();
+			}
+		}
 	}
 
 	displayArchitect() {
diff --git a/src/MapScene/Lighting/Lighting.ts b/src/MapScene/Lighting/Lighting.ts
new file mode 100644
index 0000000..04f419a
--- /dev/null
+++ b/src/MapScene/Lighting/Lighting.ts
@@ -0,0 +1,9 @@
+class Lighting {
+	constructor(...any) {
+
+	}
+
+	update() {
+		
+	}
+}
diff --git a/src/MapScene/Map/MapChunk.ts b/src/MapScene/Map/MapChunk.ts
new file mode 100644
index 0000000..76ce758
--- /dev/null
+++ b/src/MapScene/Map/MapChunk.ts
@@ -0,0 +1,90 @@
+class MapChunk {
+	static CHUNK_SIZE = 16;
+	static TILE_SIZE = 16;
+	static DIRTY_LIMIT = 32;
+
+	private pos: Vec2;
+	private map: MapData;
+	private canvas: Phaser.GameObjects.RenderTexture;
+
+	private dirtyList: Vec2[] = [];
+	private fullyDirty: boolean = false;
+
+	constructor(map: MapData, x: number, y: number) {
+		this.pos = new Vec2(x, y);
+		this.canvas = map.scene.add.renderTexture(
+			x * MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE * 4, y * MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE * 4,
+			MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE, MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE);
+
+		this.map = map;
+		this.canvas.setScale(4);
+		this.canvas.setOrigin(0, 0);
+
+		for (let i = 0; i < MapChunk.CHUNK_SIZE * MapChunk.CHUNK_SIZE; i++) {
+			let x = i % MapChunk.CHUNK_SIZE;
+			let y = Math.floor(i / MapChunk.CHUNK_SIZE);
+
+			let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+			let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+			if (mX >= this.map.size.x || mY >= this.map.size.y) continue;
+
+			this.drawTile(x, y);
+		}
+	}
+
+	dirty(pos: Vec2): void {
+		if (!this.fullyDirty) {
+			for (let v of this.dirtyList) if (v.equals(pos)) return;
+			this.dirtyList.push(pos);
+
+			if (this.dirtyList.length > MapChunk.DIRTY_LIMIT) {
+				this.fullyDirty = true;
+				this.dirtyList = [];
+			}
+		}
+	}
+
+	rebuild(): boolean {
+		if (this.fullyDirty) {
+			for (let i = 0; i < MapChunk.CHUNK_SIZE * MapChunk.CHUNK_SIZE; i++) {
+				let x = i % MapChunk.CHUNK_SIZE;
+				let y = Math.floor(i / MapChunk.CHUNK_SIZE);
+
+				let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+				let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+				if (mX >= this.map.size.x || mY >= this.map.size.y) continue;
+
+				this.drawTile(x, y);
+			}
+			this.fullyDirty = false;
+			return true;
+		}
+
+		if (this.dirtyList.length == 0) return false;
+		
+		for (let elem of this.dirtyList) this.drawTile(elem.x, elem.y);
+		this.dirtyList = [];
+		return true;
+	}
+
+	private drawTile(x: number, y: number): void {
+		let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+		let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+
+		let wallTile = this.map.getTile(Layer.wall, mX, mY);
+		if (this.map.getTileset(Layer.wall, mX, mY) == -1 || (wallTile < 54 || wallTile > 60)) {
+			this.canvas.drawFrame(this.map.manager.groundLocations[this.map.getTileset(Layer.floor, mX, mY)].key, 
+				this.map.getTile(Layer.floor, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+			
+			if (this.map.getTileset(Layer.overlay, mX, mY) != -1) 
+				this.canvas.drawFrame(this.map.manager.overlayLocations[this.map.getTileset(Layer.overlay, mX, mY)].key, 
+					this.map.getTile(Layer.overlay, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+		}
+
+		if (this.map.getTileset(Layer.wall, mX, mY) != -1) 
+			this.canvas.drawFrame(this.map.manager.wallLocations[this.map.getTileset(Layer.wall, mX, mY)].key, 
+				this.map.getTile(Layer.wall, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+
+		if ((x % 2 == 0 && y % 2 == 0) || (x % 2 != 0 && y % 2 != 0)) this.canvas.drawFrame('grid_tile', 0, x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+	}
+}
diff --git a/src/MapScene/Map/MapData.ts b/src/MapScene/Map/MapData.ts
new file mode 100644
index 0000000..0f02cd9
--- /dev/null
+++ b/src/MapScene/Map/MapData.ts
@@ -0,0 +1,138 @@
+const enum Layer {
+	floor = 0,
+	wall = 1,
+	overlay = 2
+}
+
+class MapData {
+	scene: MapScene;
+	size: Vec2;
+
+
+	manager: TilesetManager;
+	private layers: {[key: number]: { tiles: number[][], tilesets: number[][] }} = {};
+	private chunks: MapChunk[][] = [];
+
+	constructor(scene: MapScene, size: Vec2) {
+		this.scene = scene;
+		this.size = size;
+		this.manager = new TilesetManager(scene);
+
+		this.registerLayer(Layer.floor,   () => Math.floor(Math.random() * 6) + 54, 0);
+		this.registerLayer(Layer.wall,    0, -1);
+		this.registerLayer(Layer.overlay, 0, -1);	
+
+		for (let i = 0; i < Math.ceil(size.y / MapChunk.CHUNK_SIZE); i++) {
+			this.chunks[i] = [];
+			for (let j = 0; j < Math.ceil(size.x / MapChunk.CHUNK_SIZE); j++) {
+				this.chunks[i][j] = new MapChunk(this, j, i);
+			}
+		}
+	}
+
+	update(): void {
+		let start = Date.now();
+		for (let arr of this.chunks) for (let chunk of arr) {
+			chunk.rebuild();
+			if (Date.now() - start > 10) break;
+		}
+	}
+
+	setTile(layer: Layer, tileset: number, xx: number | Vec2, yy?: number): boolean {
+		let x: number, y: number;
+		if (xx instanceof Vec2) { x = xx.x; y = xx.y; }
+		else { x = xx; y = yy; }
+
+		if (x < 0 || y < 0 || x >= this.size.x || y >= this.size.y) return false;
+
+		let oldTileset = this.getTileset(layer, x, y);
+		if (oldTileset == tileset) return false;
+		this.setTileset(layer, x, y, tileset);
+		this.smartTile(x, y);
+
+		return true;
+	}
+
+	setTileset(key: number, x: number | Vec2, a?: number, b?: number): void {
+		if (x instanceof Vec2) this.layers[key].tilesets[x.y][x.x] = a;
+		else this.layers[key].tilesets[a][x] = b;
+	}
+
+	getTile(key: number, xx: number | Vec2, yy?: number): number {
+		let x: number, y: number;
+		if (xx instanceof Vec2) { x = xx.x; y = xx.y; }
+		else { x = xx; y = yy; }
+
+		return this.layers[key].tiles[clamp(y, 0, this.size.y - 1)][clamp(x, 0, this.size.x - 1)];
+	}
+
+	getTileset(key: number, xx: number | Vec2, yy?: number): number {
+		let x: number, y: number;
+		if (xx instanceof Vec2) { x = xx.x; y = xx.y; }
+		else { x = xx; y = yy; }
+
+		return this.layers[key].tilesets[clamp(y, 0, this.size.y - 1)][clamp(x, 0, this.size.x - 1)];
+	}
+
+	private smartTile(x: number, y: number): void {
+		for (let i = clamp(x - 1, this.size.x - 1, 0); i <= clamp(x + 1, this.size.x - 1, 0); i++) {
+			for (let j = clamp(y - 1, this.size.y - 1, 0); j <= clamp(y + 1, this.size.y - 1, 0); j++) {
+				const solids = this.getTilesetsAt(Layer.wall, i, j).map(i => i != -1);
+
+				const wall = SmartTiler.wall(solids, this.getTile(Layer.wall, i, j));
+				if (wall != -1) this.setTileRaw(Layer.wall, i, j, wall);
+
+				const floor = SmartTiler.floor(solids, this.getTile(Layer.floor, i, j));
+				if (floor != -1) this.setTileRaw(Layer.floor, i, j, floor);
+
+				const overlay = SmartTiler.overlay(this.getTilesetsAt(Layer.overlay, i, j)
+					.map(t => t == this.getTileset(Layer.overlay, i, j)), this.getTileset(Layer.overlay, i, j));
+				if (overlay != -1) this.setTileRaw(Layer.overlay, i, j, overlay);
+			}
+		}
+	}
+
+	private setTileRaw(key: number, x: number | Vec2, a?: number, b?: number, c?: number): void {
+		if (x instanceof Vec2) {
+			this.layers[key].tiles[x.y][x.x] = a;
+			if (b !== undefined) this.setTileset(key, x, b);
+
+			this.chunks[Math.floor(x.y / MapChunk.CHUNK_SIZE)][Math.floor(x.x / MapChunk.CHUNK_SIZE)]
+				.dirty(new Vec2(x.x % MapChunk.CHUNK_SIZE, x.y % MapChunk.CHUNK_SIZE));
+		}
+		else {
+			this.layers[key].tiles[a][x] = b;
+			if (c !== undefined) this.setTileset(key, x, a, c);
+
+			this.chunks[Math.floor(a / MapChunk.CHUNK_SIZE)][Math.floor(x / MapChunk.CHUNK_SIZE)]
+				.dirty(new Vec2(x % MapChunk.CHUNK_SIZE, a % MapChunk.CHUNK_SIZE));
+		}
+	}
+
+	private getTilesetsAt(layer: Layer, x: number, y: number): number[] {
+		let tilesets: number[] = [];
+		for (let i = -1; i <= 1; i++)
+			for (let j = -1; j <= 1; j++)
+				tilesets.push(this.getTileset(layer, clamp(x + j, 0, this.size.x - 1), clamp(y + i, 0, this.size.y - 1)));
+		return tilesets;
+	}
+
+	private registerLayer(key: number, startTile: any = 0, startTileset: number = -1): void {
+		let layer = {
+			tiles: [],
+			tilesets: []
+		}
+
+		for (let i = 0; i < this.size.y; i++) {
+			layer.tiles[i] = [];
+			layer.tilesets[i] = [];
+			for (let j = 0; j < this.size.x; j++) {
+				let tile = typeof(startTile) == "number" ? startTile : startTile();
+				layer.tiles[i][j] = tile;
+				layer.tilesets[i][j] = startTileset;
+			}
+		}
+
+		this.layers[key] = layer;
+	}
+}
diff --git a/src/map_scene/tile/SmartTiler.ts b/src/MapScene/Map/SmartTiler.ts
similarity index 98%
rename from src/map_scene/tile/SmartTiler.ts
rename to src/MapScene/Map/SmartTiler.ts
index 2cbbee3..84b14ee 100644
--- a/src/map_scene/tile/SmartTiler.ts
+++ b/src/MapScene/Map/SmartTiler.ts
@@ -219,7 +219,7 @@ namespace SmartTiler {
 		return tile;
 	}
 
-	export function ground(walls: boolean[], current: number): number {
+	export function floor(walls: boolean[], current: number): number {
 		const TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
 
 		if (current == -1) return -1;
diff --git a/src/MapScene/Map/TilesetManager.ts b/src/MapScene/Map/TilesetManager.ts
new file mode 100644
index 0000000..c301fcc
--- /dev/null
+++ b/src/MapScene/Map/TilesetManager.ts
@@ -0,0 +1,31 @@
+class TilesetManager {
+	scene: MapScene;
+
+	private currentWallInd: number = 0;
+	private currentGroundInd: number = 0;
+	private currentOverlayInd: number = 0;
+
+	wallLocations: 		{[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
+	groundLocations: 	{[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
+	overlayLocations: {[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
+	indexes:          {[key: string /*Tileset Key*/]: number} = {};
+
+	constructor(scene: MapScene) {
+		this.scene = scene;
+
+		for (let tileset of WALLS   ) this.addTileset(tileset.key, Layer.wall);
+		for (let tileset of GROUNDS ) this.addTileset(tileset.key, Layer.floor);
+		for (let tileset of OVERLAYS) this.addTileset(tileset.key, Layer.overlay);
+	}
+
+	private addTileset(key: string, layer: Layer): void {
+		let res = this.scene.textures.get(key).getSourceImage(0).width / 9;
+		let ind = (layer == Layer.wall ? this.currentWallInd : layer == Layer.floor ? this.currentGroundInd : this.currentOverlayInd);
+		this[layer == Layer.wall ? "wallLocations" : layer == Layer.floor ? "groundLocations" : "overlayLocations"][ind] = { res: res, ind: ind, key: key };
+		this.indexes[key] = ind;
+		
+		layer == Layer.wall 	? this.currentWallInd++   :
+		layer == Layer.floor  ? this.currentGroundInd++ :
+														this.currentOverlayInd++;
+	}
+}
diff --git a/src/MapScene/MapScene.ts b/src/MapScene/MapScene.ts
new file mode 100644
index 0000000..06a9839
--- /dev/null
+++ b/src/MapScene/MapScene.ts
@@ -0,0 +1,58 @@
+class MapScene extends Phaser.Scene {
+	i: InputManager;
+	
+	history: HistoryManager;
+
+	architect: ArchitectMode;
+	token: TokenMode;
+
+	world: WorldView;
+	map: MapData;
+	lighting: Lighting;
+	ui: UIView;
+
+
+	mode: number = 0;
+	tokens: Token[] = [];
+
+	constructor() { super({key: "MapScene"}); }
+
+	preload(): void {
+		window.addEventListener('resize', () => {
+			let frame = document.getElementById("game");
+			this.game.scale.resize(frame.offsetWidth, frame.offsetHeight);
+		});
+	}
+
+	create(): void {
+		this.i = new InputManager(this);
+
+		(this.game.renderer as Phaser.Renderer.WebGL.WebGLRenderer).addPipeline('outline',  new OutlinePipeline(this.game));
+		(this.game.renderer as Phaser.Renderer.WebGL.WebGLRenderer).addPipeline('brighten', new BrightenPipeline(this.game));
+
+		this.history = new HistoryManager(this);
+		this.world = new WorldView(this);
+		this.ui = new UIView(this);
+
+		const size = new Vec2(300, 300);
+
+		this.map = new MapData(this, size);
+		this.lighting = new Lighting(this, size);
+		
+		this.architect = new ArchitectMode(this);
+		this.token = new TokenMode(this);
+
+	}
+
+	update(time: number, delta: number): void {
+		this.i.update();
+
+		this.history.update();
+		this.world.update();
+		this.ui.update();
+
+		this.map.update();
+		this.lighting.update();
+	}
+}
+ 
diff --git a/src/map_scene/Token.ts b/src/MapScene/Token.ts
similarity index 100%
rename from src/map_scene/Token.ts
rename to src/MapScene/Token.ts
diff --git a/src/map_scene/WorldView.ts b/src/MapScene/WorldView.ts
similarity index 100%
rename from src/map_scene/WorldView.ts
rename to src/MapScene/WorldView.ts
diff --git a/src/shader/BrightenPipeline.ts b/src/Shaders/BrightenPipeline.ts
similarity index 100%
rename from src/shader/BrightenPipeline.ts
rename to src/Shaders/BrightenPipeline.ts
diff --git a/src/shader/OutlinePipeline.ts b/src/Shaders/OutlinePipeline.ts
similarity index 100%
rename from src/shader/OutlinePipeline.ts
rename to src/Shaders/OutlinePipeline.ts
diff --git a/src/util/InputManager.ts b/src/Util/InputManager.ts
similarity index 100%
rename from src/util/InputManager.ts
rename to src/Util/InputManager.ts
diff --git a/src/util/Util.ts b/src/Util/Util.ts
similarity index 100%
rename from src/util/Util.ts
rename to src/Util/Util.ts
diff --git a/src/util/Vector.ts b/src/Util/Vector.ts
similarity index 85%
rename from src/util/Vector.ts
rename to src/Util/Vector.ts
index 9cff228..e01958c 100644
--- a/src/util/Vector.ts
+++ b/src/Util/Vector.ts
@@ -15,6 +15,10 @@ class Vec2 {
 			this.y = (x as any as {x: number, y:number}).y;
 		}
 	}
+
+	equals(o: Vec2) {
+		return this.x == o.x && this.y == o.y;
+	}
 }
 
 class Vec3 {
@@ -42,6 +46,10 @@ class Vec3 {
 			this.z = (x as any as {x: number, y:number, z:number}).z;
 		}
 	}
+
+	equals(o: Vec3) {
+		return this.x == o.x && this.y == o.y && this.z == o.z;
+	}
 }
 
 class Vec4 {
@@ -73,4 +81,8 @@ class Vec4 {
 			this.w = (x as any).w;
 		}
 	}
+
+	equals(o: Vec4) {
+		return this.x == o.x && this.y == o.y && this.z == o.z && this.w == o.w;
+	}
 }
diff --git a/src/map_scene/FogOfWar.ts b/src/map_scene/FogOfWar.ts
deleted file mode 100644
index b630433..0000000
--- a/src/map_scene/FogOfWar.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-class FogOfWar {
-	scene: MapScene;
-
-	tex: Phaser.GameObjects.RenderTexture;
-	map: Phaser.Tilemaps.Tilemap;
-	historyLayer: Phaser.Tilemaps.DynamicTilemapLayer;
-	
-	dims: Vec2;
-
-	constructor(scene: MapScene, dims: Vec2) {
-		this.scene = scene;
-		this.dims = dims;
-
-		this.tex = new Phaser.GameObjects.RenderTexture(this.scene, 0, 0, this.dims.x*16, this.dims.y*16);
-		this.tex.setScale(4, 4);
-		this.tex.setAlpha(0.7);
-		this.scene.add.existing(this.tex);
-
-		// this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
-		// this.map.addTilesetImage("history", "wall_shadow", 16, 16, 0, 0);
-		// this.map.setLayer("history");
-		// this.historyLayer = this.map.createBlankDynamicLayer("history", "wall_shadow", 0, 0, this.dims.x, this.dims.y, 16, 16);
-		// this.historyLayer.setScale(4, 4);
-
-		// for (let i = 0; i < this.dims.x; i++) {
-		// 	for (let j = 0; j < this.dims.y; j++) {
-		// 		if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) this.historyLayer.putTileAt(0, i, j);
-		// 	}
-		// }
-
-	}
-
-	update() {
-		let resetSquare = new Phaser.GameObjects.Rectangle(this.scene, 0, 0, this.dims.x*16, this.dims.y*16, 0x000000);
-		this.tex.draw(resetSquare);
-
-		for (let token of this.scene.tokens) {
-			let startTile = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64))
-
-			let points: Vec2[] = [];
-
-			for (let i = 0; i < 288; i++) {
-				let ray = new Vec2(0.5, 0.5);
-				let dir = new Vec2(Math.cos(i * 1.25 * (Math.PI / 180)) / 32, Math.sin(i * 1.25 * (Math.PI / 180)) / 32);
-
-				let dist = 0;
-				let maxDist = 12;
-
-				while (this.scene.map.getWall(Math.floor(startTile.x + ray.x), Math.floor(startTile.y + ray.y)) == -1 && 
-					(dist = Math.sqrt(Math.pow(ray.x, 2) + Math.pow(ray.y, 2))) < maxDist) {
-					ray.x += dir.x;
-					ray.y += dir.y;
-				}
-
-				ray.x -= dir.x * maxDist * 2.4;
-				ray.y -= dir.y * maxDist * 2.4;
-
-				ray.x += dir.x * ((maxDist - dist) * 2.8);
-				ray.y += dir.y * ((maxDist - dist) * 2.8);
-
-				points.push(new Vec2(ray.x * 4, ray.y * 4));
-			}
-
-			let poly = new Phaser.GameObjects.Polygon(this.scene, token.x / 4, token.y / 4, points, 0xffffff, 0.4);
-			poly.setScale(4, 4);
-			poly.setBlendMode('ERASE');
-			poly.setDisplayOrigin(0, 0);
-			poly.setOrigin(0, 0);
-
-			for (let i = 0; i < 10; i++) {
-				poly.scaleX += 0.04;
-				poly.scaleY += 0.04;
-				// poly.x = token.x / 4 + 50 * poly.scaleX;
-				// poly.y = token.y / 4 + 50 * poly.scaleY;
-				this.tex.draw(poly);
-			}
-		}
-	}
-}
diff --git a/src/map_scene/MapScene.ts b/src/map_scene/MapScene.ts
deleted file mode 100644
index 88a5eae..0000000
--- a/src/map_scene/MapScene.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-class MapScene extends Phaser.Scene {
-	i: InputManager;
-	
-	history: HistoryManager;
-
-	architect: ArchitectMode;
-	token: TokenMode;
-
-	world: WorldView;
-	map: Tilemap;
-	ui: UIView;
-
-	fog: FogOfWar;
-
-	mode: number = 0;
-	tokens: Token[] = [];
-
-	constructor() { super({key: "MapScene"}); }
-
-	preload(): void {
-		window.addEventListener('resize', () => {
-			let frame = document.getElementById("game");
-			this.game.scale.resize(frame.offsetWidth, frame.offsetHeight);
-			// this.chat.x = -10000 + this.cameras.main.width - 309;
-		});
-	}
-
-	create(): void {
-		this.i = new InputManager(this);
-
-		(<Phaser.Renderer.WebGL.WebGLRenderer>this.game.renderer).addPipeline('outline', new OutlinePipeline(this.game));
-		(<Phaser.Renderer.WebGL.WebGLRenderer>this.game.renderer).addPipeline('brighten', new BrightenPipeline(this.game));
-
-		this.history = new HistoryManager(this);
-
-		this.world = new WorldView(this);
-		this.ui = new UIView(this);
-		this.ui.createElements();
-
-		this.map = new Tilemap("gameMap", this, 300, 300);
-		
-		this.architect = new ArchitectMode(this);
-		this.token = new TokenMode(this);
-
-		this.fog = new FogOfWar(this, new Vec2(300, 300));
-	}
-
-	update(time: number, delta: number): void {
-		this.i.update();
-
-		this.world.update();
-		this.ui.update();
-		// this.chat.update();
-		this.history.update();
-
-		this.fog.update();
-		
-		if (this.i.keyPressed('TAB')) this.mode = (this.mode == 0 ? 1 : 0);
-
-		if (this.mode == 0) {
-			if (this.ui.uiActive) this.architect.cleanup();
-			else {
-				this.architect.update();
-				this.token.cleanup();
-			}
-		}
-		else {
-			if (this.ui.uiActive) this.token.cleanup();
-			else {
-				this.token.update();
-				this.architect.cleanup();
-			}
-		}
-	}
-}
- 
diff --git a/src/map_scene/tile/Tilemap.ts b/src/map_scene/tile/Tilemap.ts
deleted file mode 100644
index 4371deb..0000000
--- a/src/map_scene/tile/Tilemap.ts
+++ /dev/null
@@ -1,183 +0,0 @@
-class Tilemap {
-	scene: MapScene;
-	map: Phaser.Tilemaps.Tilemap;
-	dimensions: Vec2 = new Vec2();
-
-	manager: TilesetManager;
-	layers: {[key: number]: Phaser.Tilemaps.DynamicTilemapLayer[]} = {};
-
-	groundAt:  number[][];
-	wallAt:    number[][];
-	overlayAt: number[][];
-
-	constructor(key: string, scene: MapScene, xwid: number, ywid: number) {
-		this.scene = scene;
-		this.dimensions = new Vec2(xwid, ywid);
-
-		this.groundAt = [];
-		this.wallAt = [];
-		this.overlayAt = [];
-		for (let i = 0; i < xwid; i++) {
-			this.groundAt[i] = [];
-			this.wallAt[i] = [];
-			this.overlayAt[i] = [];
-			for (let j = 0; j < ywid; j++) {
-				this.groundAt[i][j] = -1;
-				this.wallAt[i][j] = -1;
-				this.overlayAt[i][j] = -1;
-			}
-		}
-
-		this.manager = new TilesetManager(scene);
-
-		this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
-
-		for (let res of this.manager.resolutions()) this.createLayers(parseInt(res));
-
-		for (let x = 0; x < this.dimensions.x; x ++) {
-			for (let y = 0; y < this.dimensions.y; y ++) {
-				this.setTileRaw(x, y, 1, 54 + Math.floor(Math.random() * 6), Layer.GROUND);
-			}
-		}
-		
-		this.map.addTilesetImage("grid_tile", "grid_tile", 16, 16, 0, 0);
-		this.map.setLayer("grid");
-		let gridlayer = this.map.createBlankDynamicLayer("grid", "grid_tile", 0, 0, this.dimensions.x, this.dimensions.y, 16, 16);
-		gridlayer.setScale(4, 4);
-		gridlayer.setDepth(500);
-		for (let i = 0; i < xwid; i++) {
-			for (let j = 0; j < ywid; j++) {
-				if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) gridlayer.putTileAt(0, i, j);
-			}
-		}	
-	}
-
-	private createLayers(res: number) {
-		this.map.addTilesetImage("tileset_" + res + "_ground", 	"tileset_" + res + "_ground",  res, res, 2, 4);
-		this.map.addTilesetImage("tileset_" + res + "_wall", 		"tileset_" + res + "_wall", 	 res, res, 2, 4);
-		this.map.addTilesetImage("tileset_" + res + "_overlay", "tileset_" + res + "_overlay", res, res, 2, 4);
-
-		this.map.setLayer("layer_" + res + "_ground");
-		let ground = this.map.createBlankDynamicLayer("layer_" + res + "_ground", 
-			"tileset_" + res + "_ground", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-		ground.setScale(4 / (res / 16), 4 / (res / 16));
-		ground.setDepth(-1500 + res);
-
-		this.map.setLayer("layer_" + res + "_overlay");
-		let overlay = this.map.createBlankDynamicLayer("layer_" + res + "_overlay", 
-			"tileset_" + res + "_overlay", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-		overlay.setScale(4 / (res / 16), 4 / (res / 16));
-		overlay.setDepth(-1000 + res);
-
-		this.map.setLayer("layer_" + res + "_wall");
-		let wall = this.map.createBlankDynamicLayer("layer_" + res + "_wall", 
-			"tileset_" + res + "_wall", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-		wall.setScale(4 / (res / 16), 4 / (res / 16));
-		wall.setDepth(-500 + res);
-
-		this.layers[res] = [ground, wall, overlay];
-	}
-
-	getWall(x: number, y: number): number {
-		return this.wallAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-	}
-
-	setWall(x: number, y: number, tileset: number): boolean {
-		return this.setTile(x, y, tileset, Layer.WALL);
-	}
-
-	getGround(x: number, y: number): number {
-		return this.groundAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-	}
-
-	setGround(x: number, y: number, tileset: number): boolean {
-		return this.setTile(x, y, tileset, Layer.GROUND);
-	}
-
-	getOverlay(x: number, y: number): number {
-		return this.overlayAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-	}
-
-	setOverlay(x: number, y: number, tileset: number): boolean {
-		return this.setTile(x, y, tileset, Layer.OVERLAY);
-	}
-
-	getTile(x: number, y: number, layer: Layer) {
-		return (layer == Layer.WALL ? this.getWall(x, y) : layer == Layer.GROUND ? this.getGround(x, y) : this.getOverlay(x, y));
-	}
-
-	setTile(x: number, y: number, tileset: number, layer: Layer): boolean {
-		if (x < 0 || y < 0 || x > this.dimensions.x - 1 || y > this.dimensions.y - 1) return false;
-		
-		let arr = (layer == Layer.GROUND ? this.groundAt : layer == Layer.WALL ? this.wallAt : this.overlayAt);
-		if (arr[x][y] == tileset) return false;
-
-		if (arr[x][y] != -1) {
-			this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].removeTileAt(x, y, true);
-			arr[x][y] = -1;
-		}
-		if (tileset != -1) this.layers[this.manager.getTilesetRes(tileset, layer)][layer].putTileAt(
-			this.manager.getGlobalTileIndex(tileset, 0, layer), x, y);
-
-		arr[x][y] = tileset;
-		
-		this.calculateSmartTilesAround(x, y);
-		return true;
-	}
-
-	private setTileRaw(x: number, y: number, tileset: number, tile: number, layer: Layer): void {
-		let arr = (layer == Layer.GROUND ? this.groundAt : layer == Layer.WALL ? this.wallAt : this.overlayAt);
-
-		if (arr[x][y] != -1) {
-			this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].removeTileAt(x, y, true);
-			arr[x][y] = -1;
-		}
-
-		let loc = this.manager.getTilesetRes(tileset, layer);
-		this.layers[loc][layer].putTileAt(this.manager.getGlobalTileIndex(tileset, tile, layer), x, y);
-		arr[x][y] = tileset;
-	}
-
-	private getTileAt(x: number, y: number, layer: number): number {
-		let arr = (layer == Layer.GROUND ? this.groundAt : layer == Layer.WALL ? this.wallAt : this.overlayAt);
-		if (arr[x][y] == -1) return -1;
-		return this.manager.getLocalTileIndex(arr[x][y], this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].getTileAt(x, y, true).index, layer);
-	}
-
-	private calculateSmartTilesAround(x: number, y: number): void {
-		for (let i = clamp(x - 1, this.dimensions.x - 1, 0); i <= clamp(x + 1, this.dimensions.x - 1, 0); i++) {
-			for (let j = clamp(y - 1, this.dimensions.y - 1, 0); j <= clamp(y + 1, this.dimensions.y - 1, 0); j++) {
-
-				let wall = SmartTiler.wall(this.getWallsAround(i, j), this.getTileAt(i, j, Layer.WALL));
-				if (wall != -1) this.setTileRaw(i, j, this.wallAt[i][j], wall, Layer.WALL);
-
-				let ground = SmartTiler.ground(this.getWallsAround(i, j), this.getTileAt(i, j, Layer.GROUND));
-				if (ground != -1) this.setTileRaw(i, j, this.groundAt[i][j], ground, Layer.GROUND);
-
-				let overlay = SmartTiler.overlay(this.getOverlaysAround(i, j, this.overlayAt[i][j]), this.getTileAt(i, j, Layer.OVERLAY));
-				if (overlay != -1) this.setTileRaw(i, j, this.overlayAt[i][j], overlay, Layer.OVERLAY);
-			}
-		}
-	}
-
-	private getWallsAround(x: number, y: number): boolean[] {
-		let solid: boolean[] = [];
-		for (let i = -1; i <= 1; i++) {
-			for (let j = -1; j <= 1; j++) {
-				solid.push(this.getWall(x + j, y + i) != -1);
-			}
-		}
-		return solid;
-	}
-
-	private getOverlaysAround(x: number, y: number, targetTileset: number): boolean[] {
-		let solid: boolean[] = [];
-		for (let i = -1; i <= 1; i++) {
-			for (let j = -1; j <= 1; j++) {
-				solid.push(this.getOverlay(x + j, y + i) == targetTileset);
-			}
-		}
-		return solid;
-	}
-}
- 
diff --git a/src/map_scene/tile/TilesetCanvas.ts b/src/map_scene/tile/TilesetCanvas.ts
deleted file mode 100644
index fcd7d6d..0000000
--- a/src/map_scene/tile/TilesetCanvas.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-class TilesetCanvas {
-	manager: TilesetManager;
-
-	res: number;
-	width: number;
-	height: number;
-	
-	canvas: Phaser.Textures.CanvasTexture;
-
-	indexes: number[] = [];
-	indMap: number[] = [];
-
-	pad: number = 2;
-
-	constructor(manager: TilesetManager, res: number, layer: Layer) {
-		this.manager = manager;
-
-		this.res = res;
-		this.width = Math.floor(1024 / ((this.res + this.pad * 2) * 9));
-		this.height = Math.floor(1024 / ((this.res + this.pad * 2) * 7));
-
-		this.canvas = manager.scene.textures.createCanvas("tileset_" + res + 
-			(layer == Layer.WALL ? "_wall" : layer == Layer.GROUND ? "_ground" : "_overlay"), 
-			this.width * 9 * (this.res + this.pad * 2), this.height * 7 * (this.res + this.pad * 2));
-	}
-
-	addTileset(key: string, ind: number) {
-		const x = this.indexes.length % this.width;
-		const y = Math.floor(this.indexes.length / this.width);
-
-		this.drawTileset(key, x, y);
-		this.indMap[ind] = this.indexes.length;
-		this.indexes.push(ind);
-	}
-
-	getGlobalIndex(tileset: number, tile: number) {
-		const lX = tile % 9;
-		const lY = Math.floor(tile / 9);
-		const gX = tileset % this.width;
-		const gY = Math.floor(tileset / this.width);
-
-		const xx = lX + gX * 9;
-		const yy = lY + gY * 9;
-
-		return yy * this.width * 9 + xx;
-	}
-
-	getLocalIndex(tile: number): number {
-		const gX = tile % (this.width * 9);
-		const gY = Math.floor(tile / (this.width * 9));
-
-		const lX = gX % 9;
-		const lY = gY % 7;
-
-		return lX + lY * 9;
-	}
-
-	private drawTileset(key: string, x: number, y: number) {
-		let img: HTMLImageElement = this.manager.scene.textures.get(key).getSourceImage() as HTMLImageElement;
-		let refCanvas = document.createElement('canvas');
-		refCanvas.width = img.width;
-		refCanvas.height = img.height;
-		refCanvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
-
-		let imageOffX = 9 * (this.res + this.pad * 2) * x;
-		let imageOffY = 7 * (this.res + this.pad * 2) * y;
-
-		for (let i = 0; i < 9; i++) {
-			for (let j = 0; j < 7; j++) {
-				let frame = i + j * 9;
-
-				let tileOffX = imageOffX + i * (this.res + this.pad * 2);
-				let tileOffY = imageOffY + j * (this.res + this.pad * 2);
-
-				for (let k = 0; k < this.res + this.pad * 2; k++) {
-					for (let l = 0; l < this.pad * 2; l++) {
-
-						let sX = clamp(k - this.pad, 0, this.res - 1);
-						let sY = l < this.pad ? 0 : this.res - 1;
-						let oY = l < this.pad ? l : l + this.res;
-
-						let pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
-						this.canvas.setPixel(tileOffX + k, tileOffY + oY, pixel[0], pixel[1], pixel[2], pixel[3]);
-					}
-				}
-
-				for (let k = 0; k < this.pad * 2; k++) {
-					for (let l = 0; l < this.res; l++) {
-
-						let sX = k < this.pad ? 0 : this.res - 1;
-						let sY = clamp(l, 0, this.res - 1);
-						let oX = k < this.pad ? k : k + this.res;
-
-						let pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
-						this.canvas.setPixel(tileOffX + oX, tileOffY + l + this.pad, pixel[0], pixel[1], pixel[2], pixel[3]);
-					}
-				}
-
-				this.canvas.drawFrame(key, frame, 
-					9 * (this.res + this.pad * 2) * x + i * (this.res + this.pad * 2) + this.pad, 
-					7 * (this.res + this.pad * 2) * y + j * (this.res + this.pad * 2) + this.pad)
-			}
-		}
-
-		refCanvas.remove();
-
-	}
-}
diff --git a/src/map_scene/tile/TilesetManager.ts b/src/map_scene/tile/TilesetManager.ts
deleted file mode 100644
index 64a5a2f..0000000
--- a/src/map_scene/tile/TilesetManager.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-const enum Layer {
-	GROUND = 0,
-	WALL = 1,
-	OVERLAY = 2
-}
-
-class TilesetManager {
-	scene: MapScene;
-
-	private currentWallInd: number = 0;
-	private currentGroundInd: number = 0;
-	private currentOverlayInd: number = 0;
-
-	private wallLocations: 		{[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
-	private groundLocations: 	{[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
-	private overlayLocations: {[key: number /*Index*/]: { res: number, ind: number, key: string }} = {};
-	private canvases:    {[key: number /*Resolution*/]: TilesetCanvas[] } = {};
-	
-	indexes:    {[key: string /*Tileset Key*/]: number} = {};
-
-	constructor(scene: MapScene) {
-		this.scene = scene;
-
-		for (let tileset of WALLS  )  this.addTileset(tileset.key, Layer.WALL);
-		for (let tileset of GROUNDS)  this.addTileset(tileset.key, Layer.GROUND);
-		for (let tileset of OVERLAYS) this.addTileset(tileset.key, Layer.OVERLAY);
-	}
-
-	private addTileset(key: string, layer: Layer): void {
-		let res = this.scene.textures.get(key).getSourceImage(0).width / 9;
-
-		if (this.canvases[res] == undefined)
-			this.canvases[res] = [ new TilesetCanvas(this, res, Layer.GROUND), new TilesetCanvas(this, res, Layer.WALL), new TilesetCanvas(this, res, Layer.OVERLAY) ];
-
-		let ind = (layer == Layer.WALL ? this.currentWallInd : layer == Layer.GROUND ? this.currentGroundInd : this.currentOverlayInd);
-		let canvas = this.canvases[res];
-		this[layer == Layer.WALL ? "wallLocations" : layer == Layer.GROUND ? "groundLocations" : "overlayLocations"][ind] = { res: res, ind: ind, key: key };
-		this.indexes[key] = ind;
-		canvas[layer].addTileset(key, ind);
-		
-		layer == Layer.WALL 	? this.currentWallInd++   :
-		layer == Layer.GROUND ? this.currentGroundInd++ :
-														this.currentOverlayInd++;
-	}
-
-	resolutions(): string[] {
-		let resList: string[] = [];
-		for (let res of Object.keys(this.canvases)) resList.push(res);
-		return resList;
-	}
-
-	getTilesetRes(tileset: number, layer: Layer): number {
-		return layer == Layer.WALL ? this.wallLocations[tileset].res 
-				 : layer == Layer.GROUND ? this.groundLocations[tileset].res
-				 : this.overlayLocations[tileset].res;
-	}
-
-	getGlobalTileIndex(tileset: number, tile: number, layer: Layer): number {
-		return this.canvases[this.getTilesetRes(tileset, layer)][layer].getGlobalIndex(tileset, tile);
-	}
-
-	getLocalTileIndex(tileset: number, tile: number, layer: Layer): number {
-		return this.canvases[this.getTilesetRes(tileset, layer)][layer].getLocalIndex(tile);
-	}
-}
diff --git a/tool.js b/tool.js
index 076c9d2..c186883 100644
--- a/tool.js
+++ b/tool.js
@@ -1,22 +1,8 @@
-var __extends = (this && this.__extends) || (function () {
-    var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-    };
-    return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-    };
-})();
-var InitScene = /** @class */ (function (_super) {
-    __extends(InitScene, _super);
-    function InitScene() {
-        return _super.call(this, { key: "InitScene" }) || this;
+class InitScene extends Phaser.Scene {
+    constructor() {
+        super({ key: "InitScene" });
     }
-    InitScene.prototype.preload = function () {
+    preload() {
         this.cameras.main.setBackgroundColor("#090d24");
         this.load.text("assets", "res/_assets.txt");
         this.load.bitmapFont('font1x', '/res/font/font1.png', '/res/font/font1.fnt');
@@ -24,50 +10,46 @@ var InitScene = /** @class */ (function (_super) {
         this.load.image("logo", "res/loader/logo.png");
         this.load.spritesheet("loader_filled", "res/loader/loader_filled.png", { frameWidth: 18, frameHeight: 18 });
         this.load.spritesheet("loader_unfilled", "res/loader/loader_unfilled.png", { frameWidth: 18, frameHeight: 18 });
-    };
-    InitScene.prototype.create = function () {
-        var assets = this.cache.text.get("assets");
-        var lines = assets.split("\n");
-        var assetsParsed = "";
-        var prefixes = {};
-        lines.forEach(function (v) {
+    }
+    create() {
+        let assets = this.cache.text.get("assets");
+        let lines = assets.split("\n");
+        let assetsParsed = "";
+        let prefixes = {};
+        lines.forEach((v) => {
             if (v.substr(0, "FOLDERPREFIX".length) == "FOLDERPREFIX") {
-                var tokens = v.split(" ");
+                let tokens = v.split(" ");
                 prefixes[tokens[1]] = tokens[2];
                 return;
             }
             if (v.length == 0)
                 return;
-            var slash = v.indexOf('/');
-            var prefix = "";
+            let slash = v.indexOf('/');
+            let prefix = "";
             if (slash != -1 && prefixes[v.substr(0, slash)] != undefined)
                 prefix = prefixes[v.substr(0, slash)];
             if (slash == -1)
-                assetsParsed += v.split(" ")[0] + " " + v + "\n";
+                assetsParsed += `${v.split(" ")[0]} ${v}\n`;
             else
-                assetsParsed += "" + prefix + v.substring(slash + 1, v.length).split(" ")[0] + " " + v + "\n";
+                assetsParsed += `${prefix}${v.substring(slash + 1, v.length).split(" ")[0]} ${v}\n`;
         });
         this.cache.text.remove("assets");
         this.cache.text.add("assets", assetsParsed);
         this.game.scene.start('LoadScene');
         this.game.scene.stop('InitScene');
         this.game.scene.swapPosition('LoadScene', 'InitScene');
-    };
-    return InitScene;
-}(Phaser.Scene));
-var LoadScene = /** @class */ (function (_super) {
-    __extends(LoadScene, _super);
-    function LoadScene() {
-        var _this = _super.call(this, { key: "LoadScene" }) || this;
-        _this.patching = null;
-        _this.loadedTween = 0;
-        _this.preloading = true;
-        _this.spinTimer = 0;
-        _this.spinFrame = 0;
-        return _this;
     }
-    LoadScene.prototype.preload = function () {
-        var _this = this;
+}
+class LoadScene extends Phaser.Scene {
+    constructor() {
+        super({ key: "LoadScene" });
+        this.patching = null;
+        this.loadedTween = 0;
+        this.preloading = true;
+        this.spinTimer = 0;
+        this.spinFrame = 0;
+    }
+    preload() {
         this.cameras.main.setBackgroundColor("#090d24");
         this.loaderOutline = this.add.sprite(this.cameras.main.width / 2, this.cameras.main.height / 2 - 100, "loader_unfilled", 0);
         this.loaderOutline.setScale(6);
@@ -75,9 +57,9 @@ var LoadScene = /** @class */ (function (_super) {
         this.loaderFilled.setScale(6);
         this.add.sprite(this.cameras.main.width / 2, this.cameras.main.height - 140, "logo");
         this.text = this.add.bitmapText(this.cameras.main.width / 2 - 130, this.cameras.main.height / 2 - 20, "font2x", "Loading Assets...", 22, 1);
-        this.load.on('progress', function (val) {
-            _this.tweens.add({
-                targets: _this,
+        this.load.on('progress', (val) => {
+            this.tweens.add({
+                targets: this,
                 loadedTween: val,
                 ease: 'Cubic',
                 duration: 150,
@@ -86,8 +68,8 @@ var LoadScene = /** @class */ (function (_super) {
         });
         this.pre_update();
         this.loadAssets();
-    };
-    LoadScene.prototype.pre_update = function () {
+    }
+    pre_update() {
         if (!this.preloading)
             return;
         this.loaderFilled.setCrop(0, this.loaderFilled.height - this.loaderFilled.height * this.loadedTween, this.loaderFilled.width, this.loaderFilled.height * this.loadedTween);
@@ -100,71 +82,61 @@ var LoadScene = /** @class */ (function (_super) {
         }
         if (this.preloading)
             setTimeout(this.pre_update.bind(this), 1 / 60);
-    };
-    LoadScene.prototype.loadAssets = function () {
+    }
+    loadAssets() {
         this.load.image("loader_patching", "/res/loader/loader_patching.png");
-        for (var _i = 0, _a = this.cache.text.get("assets").split("\n"); _i < _a.length; _i++) {
-            var s = _a[_i];
-            var tokens = s.split(" ");
+        for (let s of this.cache.text.get("assets").split("\n")) {
+            let tokens = s.split(" ");
             if (tokens.length == 2)
                 this.load.image(tokens[0], "/res/" + tokens[1] + ".png");
             else if (tokens.length == 4)
                 this.load.spritesheet(tokens[0], "/res/" + tokens[1] + ".png", { frameWidth: parseInt(tokens[2]), frameHeight: parseInt(tokens[3]) });
         }
-        for (var _b = 0, TOKENS_1 = TOKENS; _b < TOKENS_1.length; _b++) {
-            var t = TOKENS_1[_b];
+        for (let t of TOKENS) {
             if (t.split_by != undefined)
                 this.load.spritesheet(t.key, t.file + ".png", { frameWidth: t.split_by, frameHeight: t.split_by });
             else
                 this.load.image(t.key, t.file + ".png");
         }
-        for (var _c = 0, WALLS_1 = WALLS; _c < WALLS_1.length; _c++) {
-            var t = WALLS_1[_c];
+        for (let t of WALLS)
             this.load.spritesheet(t.key, t.file + ".png", { frameWidth: t.res, frameHeight: t.res });
-        }
-        for (var _d = 0, GROUNDS_1 = GROUNDS; _d < GROUNDS_1.length; _d++) {
-            var t = GROUNDS_1[_d];
+        for (let t of GROUNDS)
             this.load.spritesheet(t.key, t.file + ".png", { frameWidth: t.res, frameHeight: t.res });
-        }
-        for (var _e = 0, OVERLAYS_1 = OVERLAYS; _e < OVERLAYS_1.length; _e++) {
-            var t = OVERLAYS_1[_e];
+        for (let t of OVERLAYS)
             this.load.spritesheet(t.key, t.file + ".png", { frameWidth: t.res, frameHeight: t.res });
-        }
-    };
-    LoadScene.prototype.create = function () {
-        var _this = this;
+    }
+    create() {
         this.preloading = false;
         this.loaderOutline.setFrame(0);
         this.loaderFilled.setFrame(0);
-        setTimeout(function () {
-            _this.text.setText("Loading Assets...");
-            _this.loaderFilled.setCrop(0, 0, 100, 100);
-            _this.tweens.add({
-                targets: [_this.loaderOutline, _this.loaderFilled],
+        setTimeout(() => {
+            this.text.setText("Loading Assets...");
+            this.loaderFilled.setCrop(0, 0, 100, 100);
+            this.tweens.add({
+                targets: [this.loaderOutline, this.loaderFilled],
                 y: -400,
                 alpha: 0,
                 ease: 'Cubic',
                 duration: 500,
                 repeat: 0
             });
-            setTimeout(function () {
-                _this.patching = _this.add.sprite(_this.cameras.main.width / 2, _this.cameras.main.height / 2 - 100, "loader_patching");
-                _this.patching.setScale(6);
-                _this.text.setText(" Patching Tiles...");
-                setTimeout(function () {
-                    _this.game.scene.start('MapScene');
-                    _this.game.scene.stop('LoadScene');
-                    _this.game.scene.swapPosition('MapScene', 'LoadScene');
+            setTimeout(() => {
+                this.patching = this.add.sprite(this.cameras.main.width / 2, this.cameras.main.height / 2 - 100, "loader_patching");
+                this.patching.setScale(6);
+                this.text.setText(" Loading Map...");
+                setTimeout(() => {
+                    this.game.scene.start('MapScene');
+                    this.game.scene.stop('LoadScene');
+                    this.game.scene.swapPosition('MapScene', 'LoadScene');
                 }, 100);
             }, 300);
         }, 50);
         this.cache.text.remove("assets");
-    };
-    return LoadScene;
-}(Phaser.Scene));
+    }
+}
 /// <reference path="../@types/phaser.d.ts"/>
-var game;
-window.onload = function () {
+let game;
+window.onload = () => {
     game = new DNDMapper({
         title: "DNDMapper",
         width: 1,
@@ -182,34 +154,30 @@ window.onload = function () {
         }
     });
 };
-var DNDMapper = /** @class */ (function (_super) {
-    __extends(DNDMapper, _super);
-    function DNDMapper(config) {
-        var _this = this;
-        var frame = document.getElementById("game");
+class DNDMapper extends Phaser.Game {
+    constructor(config) {
+        let frame = document.getElementById("game");
         config.width = frame.offsetWidth;
         config.height = frame.offsetHeight;
-        _this = _super.call(this, config) || this;
+        super(config);
         frame.oncontextmenu = function (e) { e.preventDefault(); };
-        return _this;
     }
-    return DNDMapper;
-}(Phaser.Game));
-var WALLS = [
+}
+const WALLS = [
     { name: "Dungeon Wall", key: "wall_dungeon", file: "res/tileset/wall_dungeon", res: 16 },
     { name: "Wood Wall", key: "wall_wood", file: "res/tileset/wall_wood", res: 16 },
     { name: "Shadow Wall", key: "wall_shadow", file: "res/tileset/wall_shadow", res: 16 },
 ];
-var GROUNDS = [
+const GROUNDS = [
     { name: "Cave Floor", key: "ground_cave", file: "res/tileset/ground_cave", res: 16 },
     { name: "Lawn", key: "ground_grass", file: "res/tileset/ground_grass", res: 16 },
     { name: "Wood Floor", key: "ground_wood", file: "res/tileset/ground_wood", res: 16 },
 ];
-var OVERLAYS = [
+const OVERLAYS = [
     { name: "Water", key: "overlay_water", file: "res/tileset/overlay_water", res: 16 },
     { name: "Hole", key: "overlay_hole", file: "res/tileset/overlay_hole", res: 16 },
 ];
-var TOKENS = [
+const TOKENS = [
     { name: "Armor 1", key: "tkn_armor_1", file: "res/token/armor_1", split_by: 18 },
     { name: "Cadin 1", key: "tkn_cadin_1", file: "res/token/cadin_1", split_by: 18 },
     { name: "Cadin 2", key: "tkn_cadin_2", file: "res/token/cadin_2", split_by: 18 },
@@ -273,133 +241,111 @@ var TOKENS = [
     { name: "Water Slime", key: "tkn_water_slime", file: "res/token/water_slime", },
     { name: "Treasure", key: "tkn_treasure", file: "res/token/treasure" },
 ];
-var FogOfWar = /** @class */ (function () {
-    function FogOfWar(scene, dims) {
-        this.scene = scene;
-        this.dims = dims;
-        this.tex = new Phaser.GameObjects.RenderTexture(this.scene, 0, 0, this.dims.x * 16, this.dims.y * 16);
-        this.tex.setScale(4, 4);
-        this.tex.setAlpha(0.7);
-        this.scene.add.existing(this.tex);
-        // this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
-        // this.map.addTilesetImage("history", "wall_shadow", 16, 16, 0, 0);
-        // this.map.setLayer("history");
-        // this.historyLayer = this.map.createBlankDynamicLayer("history", "wall_shadow", 0, 0, this.dims.x, this.dims.y, 16, 16);
-        // this.historyLayer.setScale(4, 4);
-        // for (let i = 0; i < this.dims.x; i++) {
-        // 	for (let j = 0; j < this.dims.y; j++) {
-        // 		if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) this.historyLayer.putTileAt(0, i, j);
-        // 	}
-        // }
+// class FogOfWar {
+// 	scene: MapScene;
+// 	tex: Phaser.GameObjects.RenderTexture;
+// 	map: Phaser.Tilemaps.Tilemap;
+// 	historyLayer: Phaser.Tilemaps.DynamicTilemapLayer;
+// 	dims: Vec2;
+// 	constructor(scene: MapScene, dims: Vec2) {
+// 		this.scene = scene;
+// 		this.dims = dims;
+// 		this.tex = new Phaser.GameObjects.RenderTexture(this.scene, 0, 0, this.dims.x*16, this.dims.y*16);
+// 		this.tex.setScale(4, 4);
+// 		this.tex.setAlpha(0.7);
+// 		this.scene.add.existing(this.tex);
+// 		// this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
+// 		// this.map.addTilesetImage("history", "wall_shadow", 16, 16, 0, 0);
+// 		// this.map.setLayer("history");
+// 		// this.historyLayer = this.map.createBlankDynamicLayer("history", "wall_shadow", 0, 0, this.dims.x, this.dims.y, 16, 16);
+// 		// this.historyLayer.setScale(4, 4);
+// 		// for (let i = 0; i < this.dims.x; i++) {
+// 		// 	for (let j = 0; j < this.dims.y; j++) {
+// 		// 		if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0)) this.historyLayer.putTileAt(0, i, j);
+// 		// 	}
+// 		// }
+// 	}
+// 	update() {
+// 		let resetSquare = new Phaser.GameObjects.Rectangle(this.scene, 0, 0, this.dims.x*16, this.dims.y*16, 0x000000);
+// 		this.tex.draw(resetSquare);
+// 		for (let token of this.scene.tokens) {
+// 			let startTile = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64))
+// 			let points: Vec2[] = [];
+// 			for (let i = 0; i < 288; i++) {
+// 				let ray = new Vec2(0.5, 0.5);
+// 				let dir = new Vec2(Math.cos(i * 1.25 * (Math.PI / 180)) / 32, Math.sin(i * 1.25 * (Math.PI / 180)) / 32);
+// 				let dist = 0;
+// 				let maxDist = 12;
+// 				while (this.scene.map.getWall(Math.floor(startTile.x + ray.x), Math.floor(startTile.y + ray.y)) == -1 && 
+// 					(dist = Math.sqrt(Math.pow(ray.x, 2) + Math.pow(ray.y, 2))) < maxDist) {
+// 					ray.x += dir.x;
+// 					ray.y += dir.y;
+// 				}
+// 				ray.x -= dir.x * maxDist * 2.4;
+// 				ray.y -= dir.y * maxDist * 2.4;
+// 				ray.x += dir.x * ((maxDist - dist) * 2.8);
+// 				ray.y += dir.y * ((maxDist - dist) * 2.8);
+// 				points.push(new Vec2(ray.x * 4, ray.y * 4));
+// 			}
+// 			let poly = new Phaser.GameObjects.Polygon(this.scene, token.x / 4, token.y / 4, points, 0xffffff, 0.4);
+// 			poly.setScale(4, 4);
+// 			poly.setBlendMode('ERASE');
+// 			poly.setDisplayOrigin(0, 0);
+// 			poly.setOrigin(0, 0);
+// 			for (let i = 0; i < 10; i++) {
+// 				poly.scaleX += 0.04;
+// 				poly.scaleY += 0.04;
+// 				// poly.x = token.x / 4 + 50 * poly.scaleX;
+// 				// poly.y = token.y / 4 + 50 * poly.scaleY;
+// 				this.tex.draw(poly);
+// 			}
+// 		}
+// 	}
+// }
+class MapScene extends Phaser.Scene {
+    constructor() {
+        super({ key: "MapScene" });
+        this.mode = 0;
+        this.tokens = [];
     }
-    FogOfWar.prototype.update = function () {
-        var resetSquare = new Phaser.GameObjects.Rectangle(this.scene, 0, 0, this.dims.x * 16, this.dims.y * 16, 0x000000);
-        this.tex.draw(resetSquare);
-        for (var _i = 0, _a = this.scene.tokens; _i < _a.length; _i++) {
-            var token = _a[_i];
-            var startTile = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64));
-            var points = [];
-            for (var i = 0; i < 288; i++) {
-                var ray = new Vec2(0.5, 0.5);
-                var dir = new Vec2(Math.cos(i * 1.25 * (Math.PI / 180)) / 32, Math.sin(i * 1.25 * (Math.PI / 180)) / 32);
-                var dist = 0;
-                var maxDist = 12;
-                while (this.scene.map.getWall(Math.floor(startTile.x + ray.x), Math.floor(startTile.y + ray.y)) == -1 &&
-                    (dist = Math.sqrt(Math.pow(ray.x, 2) + Math.pow(ray.y, 2))) < maxDist) {
-                    ray.x += dir.x;
-                    ray.y += dir.y;
-                }
-                ray.x -= dir.x * maxDist * 2.4;
-                ray.y -= dir.y * maxDist * 2.4;
-                ray.x += dir.x * ((maxDist - dist) * 2.8);
-                ray.y += dir.y * ((maxDist - dist) * 2.8);
-                points.push(new Vec2(ray.x * 4, ray.y * 4));
-            }
-            var poly = new Phaser.GameObjects.Polygon(this.scene, token.x / 4, token.y / 4, points, 0xffffff, 0.4);
-            poly.setScale(4, 4);
-            poly.setBlendMode('ERASE');
-            poly.setDisplayOrigin(0, 0);
-            poly.setOrigin(0, 0);
-            for (var i = 0; i < 10; i++) {
-                poly.scaleX += 0.04;
-                poly.scaleY += 0.04;
-                // poly.x = token.x / 4 + 50 * poly.scaleX;
-                // poly.y = token.y / 4 + 50 * poly.scaleY;
-                this.tex.draw(poly);
-            }
-        }
-    };
-    return FogOfWar;
-}());
-var MapScene = /** @class */ (function (_super) {
-    __extends(MapScene, _super);
-    function MapScene() {
-        var _this = _super.call(this, { key: "MapScene" }) || this;
-        _this.mode = 0;
-        _this.tokens = [];
-        return _this;
-    }
-    MapScene.prototype.preload = function () {
-        var _this = this;
-        window.addEventListener('resize', function () {
-            var frame = document.getElementById("game");
-            _this.game.scale.resize(frame.offsetWidth, frame.offsetHeight);
-            // this.chat.x = -10000 + this.cameras.main.width - 309;
+    preload() {
+        window.addEventListener('resize', () => {
+            let frame = document.getElementById("game");
+            this.game.scale.resize(frame.offsetWidth, frame.offsetHeight);
         });
-    };
-    MapScene.prototype.create = function () {
+    }
+    create() {
         this.i = new InputManager(this);
         this.game.renderer.addPipeline('outline', new OutlinePipeline(this.game));
         this.game.renderer.addPipeline('brighten', new BrightenPipeline(this.game));
         this.history = new HistoryManager(this);
         this.world = new WorldView(this);
         this.ui = new UIView(this);
-        this.ui.createElements();
-        this.map = new Tilemap("gameMap", this, 300, 300);
+        const size = new Vec2(300, 300);
+        this.map = new MapData(this, size);
+        this.lighting = new Lighting(this, size);
         this.architect = new ArchitectMode(this);
         this.token = new TokenMode(this);
-        this.fog = new FogOfWar(this, new Vec2(300, 300));
-    };
-    MapScene.prototype.update = function (time, delta) {
+    }
+    update(time, delta) {
         this.i.update();
+        this.history.update();
         this.world.update();
         this.ui.update();
-        // this.chat.update();
-        this.history.update();
-        this.fog.update();
-        if (this.i.keyPressed('TAB'))
-            this.mode = (this.mode == 0 ? 1 : 0);
-        if (this.mode == 0) {
-            if (this.ui.uiActive)
-                this.architect.cleanup();
-            else {
-                this.architect.update();
-                this.token.cleanup();
-            }
-        }
-        else {
-            if (this.ui.uiActive)
-                this.token.cleanup();
-            else {
-                this.token.update();
-                this.architect.cleanup();
-            }
-        }
-    };
-    return MapScene;
-}(Phaser.Scene));
-var Token = /** @class */ (function (_super) {
-    __extends(Token, _super);
-    function Token(scene, x, y, tex) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.sprite = null;
-        _this.shadow = null;
-        _this.currentFrame = 0;
-        _this.setTexture(tex);
-        _this.uuid = generateId(32);
-        return _this;
+        this.map.update();
+        this.lighting.update();
     }
-    Token.prototype.setTexture = function (tex) {
+}
+class Token extends Phaser.GameObjects.Container {
+    constructor(scene, x, y, tex) {
+        super(scene, x, y);
+        this.sprite = null;
+        this.shadow = null;
+        this.currentFrame = 0;
+        this.setTexture(tex);
+        this.uuid = generateId(32);
+    }
+    setTexture(tex) {
         if (this.shadow != null)
             this.shadow.setTexture(tex);
         else {
@@ -422,19 +368,19 @@ var Token = /** @class */ (function (_super) {
             this.setPosition(this.x / 4, this.y / 4);
             this.list.push(this.sprite);
         }
-    };
-    Token.prototype.setFrame = function (frame) {
+    }
+    setFrame(frame) {
         this.currentFrame = frame;
         this.sprite.setFrame(frame);
         this.shadow.setFrame(frame);
-    };
-    Token.prototype.getFrame = function () {
+    }
+    getFrame() {
         return this.currentFrame;
-    };
-    Token.prototype.frameCount = function () {
+    }
+    frameCount() {
         return Object.keys(this.sprite.texture.frames).length - 1;
-    };
-    Token.prototype.setHovered = function (hovered) {
+    }
+    setHovered(hovered) {
         if (this.hovered == hovered)
             return;
         this.hovered = hovered;
@@ -444,8 +390,8 @@ var Token = /** @class */ (function (_super) {
         }
         if (!this.selected)
             this.sprite.setPipeline("brighten");
-    };
-    Token.prototype.setSelected = function (selected) {
+    }
+    setSelected(selected) {
         if (this.selected == selected)
             return;
         this.selected = selected;
@@ -459,16 +405,16 @@ var Token = /** @class */ (function (_super) {
             this.sprite.setPipeline("outline");
             this.sprite.pipeline.setFloat1("tex_size", this.sprite.texture.source[0].width);
         }
-    };
-    Token.prototype.setPosition = function (x, y, z, w) {
+    }
+    setPosition(x, y, z, w) {
         Phaser.GameObjects.Container.prototype.setPosition.call(this, x * 4, y * 4, z, w);
         return this;
-    };
-    Token.prototype.getPosition = function () {
+    }
+    getPosition() {
         return new Vec2(this.x / 4, this.y / 4);
-    };
+    }
     // Serialization Methods
-    Token.prototype.serialize = function () {
+    serialize() {
         return JSON.stringify({
             uuid: this.uuid,
             sprite: this.sprite.texture.key,
@@ -476,23 +422,22 @@ var Token = /** @class */ (function (_super) {
             x: this.x / 4,
             y: this.y / 4
         });
-    };
-    Token.deserialize = function (scene, serialized) {
-        var tkn = new Token(scene, 0, 0, "");
+    }
+    static deserialize(scene, serialized) {
+        let tkn = new Token(scene, 0, 0, "");
         tkn.loadSerializedData(serialized);
         return tkn;
-    };
-    Token.prototype.loadSerializedData = function (serialized) {
-        var tbl = JSON.parse(serialized);
+    }
+    loadSerializedData(serialized) {
+        let tbl = JSON.parse(serialized);
         this.uuid = tbl.uuid;
         this.setTexture(tbl.sprite);
         this.setFrame(tbl.frame);
         this.setPosition(tbl.x, tbl.y);
-    };
-    return Token;
-}(Phaser.GameObjects.Container));
-var WorldView = /** @class */ (function () {
-    function WorldView(scene) {
+    }
+}
+class WorldView {
+    constructor(scene) {
         this.cursorScreen = new Vec2();
         this.lastCursorScreen = new Vec2();
         this.cursorWorld = new Vec2();
@@ -503,75 +448,69 @@ var WorldView = /** @class */ (function () {
         this.camera = this.scene.cameras.main;
         this.init();
     }
-    WorldView.prototype.init = function () {
-        var _this = this;
+    init() {
         this.camera.setBackgroundColor("#090d24");
         // Bind the scroll wheel event
         this.onWheel = this.onWheel.bind(this);
         document.documentElement.addEventListener("wheel", this.onWheel);
-        this.scene.events.on('destroy', function () { return document.documentElement.removeEventListener("wheel", _this.onWheel); });
-    };
-    WorldView.prototype.onWheel = function (e) {
+        this.scene.events.on('destroy', () => document.documentElement.removeEventListener("wheel", this.onWheel));
+    }
+    onWheel(e) {
         if (!this.scene.token.movingTokens && !this.scene.ui.uiActive) {
-            var dir = (e.deltaY < 0 ? 1 : -1);
+            let dir = (e.deltaY < 0 ? 1 : -1);
             this.zoomLevel = clamp(this.zoomLevel + dir, 0, this.zoomLevels.length - 1);
             this.camera.setZoom(this.zoomLevels[this.zoomLevel] / 100);
         }
-    };
-    WorldView.prototype.pan = function () {
+    }
+    pan() {
         if (this.scene.input.activePointer.middleButtonDown()) {
             this.camera.scrollX += Math.round((this.lastCursorScreen.x - this.cursorScreen.x) / this.camera.zoom);
             this.camera.scrollY += Math.round((this.lastCursorScreen.y - this.cursorScreen.y) / this.camera.zoom);
         }
-    };
-    WorldView.prototype.update = function () {
+    }
+    update() {
         this.lastCursorScreen = this.cursorScreen;
         this.lastCursorWorld = this.cursorWorld;
         this.cursorScreen = new Vec2(this.scene.input.mousePointer.x, this.scene.input.mousePointer.y);
         this.cursorWorld = new Vec2(this.cursorScreen.x / this.camera.zoom + this.camera.scrollX - ((this.camera.displayWidth - this.camera.width) / 2), this.cursorScreen.y / this.camera.zoom + this.camera.scrollY - ((this.camera.displayHeight - this.camera.height) / 2));
         this.pan();
-    };
-    return WorldView;
-}());
-var HistoryElement = /** @class */ (function () {
-    function HistoryElement(scene, type, data) {
+    }
+}
+class HistoryElement {
+    constructor(scene, type, data) {
         this.scene = scene;
         this.type = type;
         this.data = data;
     }
-    HistoryElement.prototype.undo = function () {
-        var _this = this;
+    undo() {
         console.log("Undo", this.type);
         if (this.type == "tile") {
-            for (var _i = 0, _a = this.data; _i < _a.length; _i++) {
-                var tile = _a[_i];
-                this.scene.map.setTile(tile.pos.x, tile.pos.y, tile.lastTile, tile.layer);
-            }
+            for (let tile of this.data)
+                this.scene.map.setTile(tile.layer, tile.lastTile, tile.pos.x, tile.pos.y);
         }
         else if (this.type == "token_modify") {
-            var data = this.data;
-            for (var i = 0; i < data.old.length; i++) {
-                var uuid = JSON.parse(this.data.old[i]).uuid;
-                var found = false;
-                for (var _b = 0, _c = this.scene.tokens; _b < _c.length; _b++) {
-                    var token_1 = _c[_b];
-                    if (token_1.uuid == uuid) {
-                        token_1.loadSerializedData(this.data.old[i]);
+            let data = this.data;
+            for (let i = 0; i < data.old.length; i++) {
+                let uuid = JSON.parse(this.data.old[i]).uuid;
+                let found = false;
+                for (let token of this.scene.tokens) {
+                    if (token.uuid == uuid) {
+                        token.loadSerializedData(this.data.old[i]);
                         found = true;
                         break;
                     }
                 }
                 if (found)
                     continue;
-                var token = new Token(this.scene, 0, 0, "");
+                let token = new Token(this.scene, 0, 0, "");
                 token.loadSerializedData(this.data.old[i]);
                 this.scene.add.existing(token);
                 this.scene.tokens.push(token);
             }
         }
         else if (this.type == "token_create") {
-            var uuid = JSON.parse(this.data.data).uuid;
-            for (var i = 0; i < this.scene.tokens.length; i++) {
+            let uuid = JSON.parse(this.data.data).uuid;
+            for (let i = 0; i < this.scene.tokens.length; i++) {
                 if (this.scene.tokens[i].uuid == uuid) {
                     this.scene.token.removeToken(this.scene.tokens[i]);
                     break;
@@ -579,82 +518,77 @@ var HistoryElement = /** @class */ (function () {
             }
         }
         else if (this.type == "token_delete") {
-            this.data.data.forEach(function (ser) {
-                var token = new Token(_this.scene, 0, 0, "");
+            this.data.data.forEach(ser => {
+                let token = new Token(this.scene, 0, 0, "");
                 token.loadSerializedData(ser);
-                _this.scene.add.existing(token);
-                _this.scene.tokens.push(token);
+                this.scene.add.existing(token);
+                this.scene.tokens.push(token);
             });
         }
-    };
-    HistoryElement.prototype.redo = function () {
-        var _this = this;
+    }
+    redo() {
         console.log("Redo", this.type);
         if (this.type == "tile") {
-            for (var _i = 0, _a = this.data; _i < _a.length; _i++) {
-                var tile = _a[_i];
-                this.scene.map.setTile(tile.pos.x, tile.pos.y, tile.tile, tile.layer);
-            }
+            for (let tile of this.data)
+                this.scene.map.setTile(tile.layer, tile.tile, tile.pos.x, tile.pos.y);
         }
         else if (this.type == "token_modify") {
-            var data = this.data;
-            for (var i = 0; i < data.new.length; i++) {
-                var uuid = JSON.parse(this.data.new[i]).uuid;
-                var found = false;
-                for (var _b = 0, _c = this.scene.tokens; _b < _c.length; _b++) {
-                    var token_2 = _c[_b];
-                    if (token_2.uuid == uuid) {
-                        token_2.loadSerializedData(this.data.new[i]);
+            let data = this.data;
+            for (let i = 0; i < data.new.length; i++) {
+                let uuid = JSON.parse(this.data.new[i]).uuid;
+                let found = false;
+                for (let token of this.scene.tokens) {
+                    if (token.uuid == uuid) {
+                        token.loadSerializedData(this.data.new[i]);
                         found = true;
                         break;
                     }
                 }
                 if (found)
                     continue;
-                var token = new Token(this.scene, 0, 0, "");
+                let token = new Token(this.scene, 0, 0, "");
                 token.loadSerializedData(this.data.new[i]);
                 this.scene.add.existing(token);
                 this.scene.tokens.push(token);
             }
         }
         else if (this.type == "token_create") {
-            var data = JSON.parse(this.data.data);
-            var token = new Token(this.scene, 0, 0, "");
+            let data = JSON.parse(this.data.data);
+            let token = new Token(this.scene, 0, 0, "");
             token.loadSerializedData(this.data.data);
             this.scene.add.existing(token);
             this.scene.tokens.push(token);
         }
         else if (this.type == "token_delete") {
-            this.data.data.forEach(function (ser) {
-                var t = JSON.parse(ser);
-                if (_this.scene.token.hoveredToken != null && _this.scene.token.hoveredToken.uuid == t.uuid)
-                    _this.scene.token.hoveredToken = null;
-                for (var i = 0; i < _this.scene.token.selectedTokens.length; i++) {
-                    if (_this.scene.token.selectedTokens[i].uuid == t.uuid) {
-                        _this.scene.token.selectedTokens.splice(i, 1);
+            this.data.data.forEach(ser => {
+                let t = JSON.parse(ser);
+                if (this.scene.token.hoveredToken != null && this.scene.token.hoveredToken.uuid == t.uuid)
+                    this.scene.token.hoveredToken = null;
+                for (let i = 0; i < this.scene.token.selectedTokens.length; i++) {
+                    if (this.scene.token.selectedTokens[i].uuid == t.uuid) {
+                        this.scene.token.selectedTokens.splice(i, 1);
                         break;
                     }
                 }
-                for (var i = 0; i < _this.scene.tokens.length; i++) {
-                    if (_this.scene.tokens[i].uuid == t.uuid) {
-                        _this.scene.tokens[i].destroy();
-                        _this.scene.tokens.splice(i, 1);
+                for (let i = 0; i < this.scene.tokens.length; i++) {
+                    if (this.scene.tokens[i].uuid == t.uuid) {
+                        this.scene.tokens[i].destroy();
+                        this.scene.tokens.splice(i, 1);
                         break;
                     }
                 }
             });
         }
-    };
-    return HistoryElement;
-}());
-var HistoryManager = /** @class */ (function () {
-    function HistoryManager(scene) {
+    }
+}
+class HistoryManager {
+    constructor(scene) {
         this.history = [];
         this.historyHead = -1;
         this.timeHoldingHistoryKey = 0;
         this.scene = scene;
     }
-    HistoryManager.prototype.update = function () {
+    update() {
         if (this.scene.i.keyPressed('Z')) {
             this.timeHoldingHistoryKey = 0;
             if (!this.scene.i.keyDown('SHIFT'))
@@ -677,41 +611,38 @@ var HistoryManager = /** @class */ (function () {
         }
         else
             this.timeHoldingHistoryKey = 0;
-    };
-    HistoryManager.prototype.push = function (type, data) {
+    }
+    push(type, data) {
         this.history.splice(this.historyHead + 1, this.history.length - this.historyHead, new HistoryElement(this.scene, type, data));
         this.historyHead = this.history.length - 1;
-    };
-    HistoryManager.prototype.undo = function () {
+    }
+    undo() {
         if (this.historyHead >= 0) {
             this.history[this.historyHead].undo();
             this.historyHead--;
         }
-    };
-    HistoryManager.prototype.redo = function () {
+    }
+    redo() {
         if (this.historyHead < this.history.length - 1) {
             this.historyHead++;
             this.history[this.historyHead].redo();
         }
-    };
-    return HistoryManager;
-}());
-var Chat = /** @class */ (function (_super) {
-    __extends(Chat, _super);
-    function Chat(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.messages = [];
-        _this.textInput = new TextInput(scene, 0, 0);
-        _this.list.push(_this.textInput);
-        _this.messageContainer = new Phaser.GameObjects.Container(scene, 0, 0);
-        _this.list.push(_this.messageContainer);
-        return _this;
     }
-    Chat.prototype.update = function () {
+}
+class Chat extends Phaser.GameObjects.Container {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.messages = [];
+        this.textInput = new TextInput(scene, 0, 0);
+        this.list.push(this.textInput);
+        this.messageContainer = new Phaser.GameObjects.Container(scene, 0, 0);
+        this.list.push(this.messageContainer);
+    }
+    update() {
         this.textInput.y = -this.textInput.getHeight();
         this.messageContainer.y = this.textInput.y - 3;
-    };
-    Chat.prototype.pushMessage = function (message) {
+    }
+    pushMessage(message) {
         this.messages.unshift(new ChatBox(this.scene, 0, 0, message));
         this.messageContainer.list.push(this.messages[0]);
         this.scene.tweens.add({
@@ -722,11 +653,10 @@ var Chat = /** @class */ (function (_super) {
             repeat: 0
         });
         this.reflowMessages();
-    };
-    Chat.prototype.reflowMessages = function () {
-        var y = 0;
-        for (var _i = 0, _a = this.messages; _i < _a.length; _i++) {
-            var message = _a[_i];
+    }
+    reflowMessages() {
+        let y = 0;
+        for (let message of this.messages) {
             y -= message.getHeight() + 9;
             if (y + message.getHeight() < -400) {
                 this.scene.tweens.add({
@@ -745,81 +675,74 @@ var Chat = /** @class */ (function (_super) {
                 repeat: 0
             });
         }
-    };
-    return Chat;
-}(Phaser.GameObjects.Container));
-var ChatBox = /** @class */ (function (_super) {
-    __extends(ChatBox, _super);
-    function ChatBox(scene, x, y, str, tex) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.texture = "ui_text_box";
-        _this.FONT_SIZE = 4.3;
-        _this.chatboxHeight = 0;
-        _this.str = str;
-        if (tex != undefined)
-            _this.texture = tex;
-        _this.setText(str);
-        return _this;
     }
-    ChatBox.prototype.setText = function (text) {
-        this.list.forEach(function (e) { return e.destroy(); });
+}
+class ChatBox extends Phaser.GameObjects.Container {
+    constructor(scene, x, y, str, tex) {
+        super(scene, x, y);
+        this.texture = "ui_text_box";
+        this.FONT_SIZE = 4.3;
+        this.chatboxHeight = 0;
+        this.str = str;
+        if (tex != undefined)
+            this.texture = tex;
+        this.setText(str);
+    }
+    setText(text) {
+        this.list.forEach((e) => e.destroy());
         this.list = [];
         this.str = text;
-        var testObj = new Phaser.GameObjects.BitmapText(this.scene, 15, 4, "font2x", "AB", this.FONT_SIZE, 0);
-        var letterWidth = testObj.getTextBounds().global.width / 2;
-        var maxLetters = 95 / letterWidth;
-        var split = this.str.split(/( )/g);
-        var lines = [];
+        let testObj = new Phaser.GameObjects.BitmapText(this.scene, 15, 4, "font2x", "AB", this.FONT_SIZE, 0);
+        const letterWidth = testObj.getTextBounds().global.width / 2;
+        const maxLetters = 95 / letterWidth;
+        const split = this.str.split(/( )/g);
+        let lines = [];
         function nextLine() {
-            var newLine = "";
-            while ((newLine + " " + split[0]).length < maxLetters && split.length)
+            let newLine = "";
+            while (`${newLine} ${split[0]}`.length < maxLetters && split.length)
                 newLine += split.shift();
             lines.push(newLine.trim());
             if (split.length)
                 nextLine();
         }
         nextLine();
-        var top = new Phaser.GameObjects.Sprite(this.scene, 0, 0, this.texture, 0);
+        let top = new Phaser.GameObjects.Sprite(this.scene, 0, 0, this.texture, 0);
         top.setScale(3, 3);
         top.setOrigin(0, 0);
         top.setAlpha(0.6);
         this.list.push(top);
-        var i = 0;
-        for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
-            var line = lines_1[_i];
-            var elem = new Phaser.GameObjects.BitmapText(this.scene, 12, 7 + i * 18, "font2x", line, this.FONT_SIZE, 0);
+        let i = 0;
+        for (let line of lines) {
+            let elem = new Phaser.GameObjects.BitmapText(this.scene, 12, 7 + i * 18, "font2x", line, this.FONT_SIZE, 0);
             elem.setScale(3, 3);
             elem.setOrigin(0, 0);
             this.list.push(elem);
             i++;
         }
-        var lastElem = this.list[this.list.length - 1];
-        var height = Math.max(lastElem.y + lastElem.getTextBounds().global.height - 36, 2);
-        var middle = new Phaser.GameObjects.Sprite(this.scene, 0, 18, "ui_text_box", 1);
+        let lastElem = this.list[this.list.length - 1];
+        let height = Math.max(lastElem.y + lastElem.getTextBounds().global.height - 36, 2);
+        let middle = new Phaser.GameObjects.Sprite(this.scene, 0, 18, "ui_text_box", 1);
         middle.setScale(3, height / 6);
         middle.setOrigin(0, 0);
         middle.setAlpha(0.6);
         this.list.push(middle);
         this.sendToBack(middle);
-        var bottom = new Phaser.GameObjects.Sprite(this.scene, 0, height + 18, this.texture, 2);
+        let bottom = new Phaser.GameObjects.Sprite(this.scene, 0, height + 18, this.texture, 2);
         bottom.setScale(3, 3);
         bottom.setOrigin(0, 0);
         bottom.setAlpha(0.6);
         this.list.push(bottom);
         this.sendToBack(bottom);
         this.chatboxHeight = height + 18 * 2;
-    };
-    ChatBox.prototype.getHeight = function () {
+    }
+    getHeight() {
         return this.chatboxHeight;
-    };
-    return ChatBox;
-}(Phaser.GameObjects.Container));
-var TextInput = /** @class */ (function (_super) {
-    __extends(TextInput, _super);
-    function TextInput(scene, x, y) {
-        var _this = _super.call(this, scene, x, y, " ", "ui_text_input") || this;
-        _this.text = "";
-        return _this;
+    }
+}
+class TextInput extends ChatBox {
+    constructor(scene, x, y) {
+        super(scene, x, y, " ", "ui_text_input");
+        this.text = "";
         // document.addEventListener("keydown", (e) => {
         // 	let code = e.keyCode;
         // 	if (code == 8) {
@@ -836,10 +759,9 @@ var TextInput = /** @class */ (function (_super) {
         // 	this.setText(this.text.length == 0 ? " " : this.text);
         // })
     }
-    return TextInput;
-}(ChatBox));
-var UIView = /** @class */ (function () {
-    function UIView(scene) {
+}
+class UIView {
+    constructor(scene) {
         this.visibleMenu = 0;
         this.uiActive = false;
         this.sidebarOpen = true;
@@ -847,15 +769,15 @@ var UIView = /** @class */ (function () {
         this.camera = this.scene.cameras.add(0, 0, this.scene.cameras.main.width, this.scene.cameras.main.height, false, "ui_camera");
         this.camera.scrollX = -10000;
         this.o = this.scene.add.container(-10000, 0);
+        this.createElements();
     }
-    UIView.prototype.createElements = function () {
+    createElements() {
         this.o.add(new UISidebarToggle(this.scene, 16, 1));
         this.o.add(new UIModeSwitchButton(this.scene, 28, 1));
         this.o.add(new UIHistoryManipulation(this.scene, 43, 1));
         this.tokenSidebar = new UITokenSidebar(this.scene, -205, 0);
         this.o.add(this.tokenSidebar);
-        for (var _i = 0, TOKENS_2 = TOKENS; _i < TOKENS_2.length; _i++) {
-            var t = TOKENS_2[_i];
+        for (let t of TOKENS) {
             this.tokenSidebar.addToken(t.key);
         }
         this.tileSidebar = new UITileSidebar(this.scene, 0, 0);
@@ -863,10 +785,9 @@ var UIView = /** @class */ (function () {
         this.tokenProps = new UITokenProps(this.scene, 24, 0);
         this.tokenProps.y = this.camera.height;
         this.o.add(this.tokenProps);
-    };
-    UIView.prototype.toggleSidebarOpen = function () {
-        var _this = this;
-        var sidebarOpen = !this.sidebarOpen;
+    }
+    toggleSidebarOpen() {
+        let sidebarOpen = !this.sidebarOpen;
         this.scene.tweens.add({
             targets: this.o,
             x: { from: (sidebarOpen ? -10204 : -10000), to: (sidebarOpen ? -10000 : -10204) },
@@ -881,12 +802,11 @@ var UIView = /** @class */ (function () {
             duration: 225,
             repeat: 0
         });
-        setTimeout(function () { return _this.sidebarOpen = sidebarOpen; }, 0); // Hack to prevent multiple UI items from triggering.
-    };
-    UIView.prototype.update = function () {
+        setTimeout(() => this.sidebarOpen = sidebarOpen, 0); // Hack to prevent multiple UI items from triggering.
+    }
+    update() {
         this.uiActive = false;
-        for (var _i = 0, _a = this.o.list; _i < _a.length; _i++) {
-            var o = _a[_i];
+        for (let o of this.o.list) {
             o.update();
             if (!this.uiActive && o.mouseIntersects())
                 this.uiActive = true;
@@ -902,8 +822,26 @@ var UIView = /** @class */ (function () {
                 this.displayToken();
             }
         }
-    };
-    UIView.prototype.displayArchitect = function () {
+        if (this.scene.i.keyPressed('TAB'))
+            this.scene.mode = (this.scene.mode == 0 ? 1 : 0);
+        if (this.scene.mode == 0) {
+            if (this.uiActive)
+                this.scene.architect.cleanup();
+            else {
+                this.scene.architect.update();
+                this.scene.token.cleanup();
+            }
+        }
+        else {
+            if (this.uiActive)
+                this.scene.token.cleanup();
+            else {
+                this.scene.token.update();
+                this.scene.architect.cleanup();
+            }
+        }
+    }
+    displayArchitect() {
         this.o.bringToTop(this.tileSidebar);
         this.tileSidebar.x = -205;
         this.scene.tweens.add({
@@ -913,8 +851,8 @@ var UIView = /** @class */ (function () {
             duration: 300,
             repeat: 0
         });
-    };
-    UIView.prototype.hideToken = function () {
+    }
+    hideToken() {
         this.scene.tweens.add({
             targets: this.tokenSidebar,
             x: { from: 0, to: -60 },
@@ -930,8 +868,8 @@ var UIView = /** @class */ (function () {
             duration: 300,
             repeat: 0
         });
-    };
-    UIView.prototype.displayToken = function () {
+    }
+    displayToken() {
         this.o.bringToTop(this.tokenSidebar);
         this.tokenSidebar.x = -205;
         this.scene.tweens.add({
@@ -950,8 +888,8 @@ var UIView = /** @class */ (function () {
             duration: 300,
             repeat: 0
         });
-    };
-    UIView.prototype.hideArchitect = function () {
+    }
+    hideArchitect() {
         this.scene.tweens.add({
             targets: this.tileSidebar,
             x: { from: 0, to: -60 },
@@ -959,83 +897,72 @@ var UIView = /** @class */ (function () {
             duration: 300,
             repeat: 0
         });
-    };
-    return UIView;
-}());
-var UIComponent = /** @class */ (function (_super) {
-    __extends(UIComponent, _super);
-    function UIComponent(scene, x, y, tex) {
-        var _this = _super.call(this, scene, x, y, tex) || this;
-        _this.setOrigin(0, 0);
-        _this.setScale(3, 3);
-        _this.setPos(x * 3, y * 3);
-        _this.setActive(true);
-        _this.scene.add.existing(_this);
-        return _this;
     }
-    UIComponent.prototype.setPos = function (x, y) {
+}
+class UIComponent extends Phaser.GameObjects.Sprite {
+    constructor(scene, x, y, tex) {
+        super(scene, x, y, tex);
+        this.setOrigin(0, 0);
+        this.setScale(3, 3);
+        this.setPos(x * 3, y * 3);
+        this.setActive(true);
+        this.scene.add.existing(this);
+    }
+    setPos(x, y) {
         this.setPosition(x * 3, y * 3);
-    };
-    UIComponent.prototype.mouseIntersects = function () {
-        var pointer = this.scene.input.mousePointer;
-        var xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
+    }
+    mouseIntersects() {
+        let pointer = this.scene.input.mousePointer;
+        let xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
         return (pointer.x + xO >= this.x && pointer.y >= this.y && pointer.x + xO <= this.x + this.width * 3 && pointer.y <= this.y + this.height * 3);
-    };
-    UIComponent.prototype.mousePos = function () {
-        var pointer = this.scene.input.mousePointer;
-        var xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
-        return new Vec2(Math.round((pointer.x + xO - this.x) / 3), Math.round((pointer.y - this.y) / 3));
-    };
-    return UIComponent;
-}(Phaser.GameObjects.Sprite));
-var UIContainer = /** @class */ (function (_super) {
-    __extends(UIContainer, _super);
-    function UIContainer(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.intersects = [];
-        _this.setPos(x * 3, y * 3);
-        _this.setActive(true);
-        _this.scene.add.existing(_this);
-        return _this;
     }
-    UIContainer.prototype.setPos = function (x, y) {
+    mousePos() {
+        let pointer = this.scene.input.mousePointer;
+        let xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
+        return new Vec2(Math.round((pointer.x + xO - this.x) / 3), Math.round((pointer.y - this.y) / 3));
+    }
+}
+class UIContainer extends Phaser.GameObjects.Container {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.intersects = [];
+        this.setPos(x * 3, y * 3);
+        this.setActive(true);
+        this.scene.add.existing(this);
+    }
+    setPos(x, y) {
         this.setPosition(x * 3, y * 3);
-    };
-    UIContainer.prototype.mouseIntersects = function () {
-        for (var _i = 0, _a = this.list; _i < _a.length; _i++) {
-            var i = _a[_i];
+    }
+    mouseIntersects() {
+        for (let i of this.list) {
             if (i.mouseIntersects != null)
                 if (i.mouseIntersects())
                     return true;
         }
-        for (var _b = 0, _c = this.intersects; _b < _c.length; _b++) {
-            var i = _c[_b];
-            var pointer = this.scene.input.mousePointer;
-            var xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
+        for (let i of this.intersects) {
+            let pointer = this.scene.input.mousePointer;
+            let xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
             if (pointer.x + xO >= this.x + i.x && pointer.y >= this.y + i.y
                 && pointer.x + xO <= this.x + i.x + i.width * i.scaleX && pointer.y <= this.y + i.y + i.height * i.scaleY)
                 return true;
         }
         return false;
-    };
-    UIContainer.prototype.mousePos = function () {
-        var pointer = this.scene.input.mousePointer;
-        var xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
-        return new Vec2(Math.round((pointer.x + xO - this.x) / 3), Math.round((pointer.y - this.y) / 3));
-    };
-    return UIContainer;
-}(Phaser.GameObjects.Container));
-var UIHistoryManipulation = /** @class */ (function (_super) {
-    __extends(UIHistoryManipulation, _super);
-    function UIHistoryManipulation(scene, x, y) {
-        var _this = _super.call(this, scene, x, y, "ui_history_manipulation") || this;
-        _this.scene = scene;
-        _this.setActive(true);
-        return _this;
     }
-    UIHistoryManipulation.prototype.update = function () {
-        var hasNext = this.scene.history.historyHead < this.scene.history.history.length - 1;
-        var hasPrev = this.scene.history.historyHead >= 0;
+    mousePos() {
+        let pointer = this.scene.input.mousePointer;
+        let xO = (this.scene.ui.sidebarOpen) ? 0 : 204;
+        return new Vec2(Math.round((pointer.x + xO - this.x) / 3), Math.round((pointer.y - this.y) / 3));
+    }
+}
+class UIHistoryManipulation extends UIComponent {
+    constructor(scene, x, y) {
+        super(scene, x, y, "ui_history_manipulation");
+        this.scene = scene;
+        this.setActive(true);
+    }
+    update() {
+        let hasNext = this.scene.history.historyHead < this.scene.history.history.length - 1;
+        let hasPrev = this.scene.history.historyHead >= 0;
         if (hasNext && hasPrev) {
             if (this.mouseIntersects() && this.mousePos().x > 19) {
                 this.setFrame(2);
@@ -1074,18 +1001,15 @@ var UIHistoryManipulation = /** @class */ (function (_super) {
         }
         else
             this.setFrame(4);
-    };
-    return UIHistoryManipulation;
-}(UIComponent));
-var UIModeSwitchButton = /** @class */ (function (_super) {
-    __extends(UIModeSwitchButton, _super);
-    function UIModeSwitchButton(scene, x, y) {
-        var _this = _super.call(this, scene, x, y, "ui_mode_switch") || this;
-        _this.scene = scene;
-        _this.setActive(true);
-        return _this;
     }
-    UIModeSwitchButton.prototype.update = function () {
+}
+class UIModeSwitchButton extends UIComponent {
+    constructor(scene, x, y) {
+        super(scene, x, y, "ui_mode_switch");
+        this.scene = scene;
+        this.setActive(true);
+    }
+    update() {
         if (this.mouseIntersects()) {
             if (this.scene.mode == 0) {
                 if (this.mousePos().x > 19) {
@@ -1112,18 +1036,15 @@ var UIModeSwitchButton = /** @class */ (function (_super) {
             else
                 this.setFrame(0);
         }
-    };
-    return UIModeSwitchButton;
-}(UIComponent));
-var UISideMenuButton = /** @class */ (function (_super) {
-    __extends(UISideMenuButton, _super);
-    function UISideMenuButton(scene, x, y) {
-        var _this = _super.call(this, scene, x, y, "ui_button_side_menu") || this;
-        _this.scene = scene;
-        _this.setActive(true);
-        return _this;
     }
-    UISideMenuButton.prototype.update = function () {
+}
+class UISideMenuButton extends UIComponent {
+    constructor(scene, x, y) {
+        super(scene, x, y, "ui_button_side_menu");
+        this.scene = scene;
+        this.setActive(true);
+    }
+    update() {
         if (this.mouseIntersects()) {
             if (this.scene.i.mouseLeftPressed()) {
                 this.setFrame(2);
@@ -1134,46 +1055,43 @@ var UISideMenuButton = /** @class */ (function (_super) {
         else {
             this.setFrame(0);
         }
-    };
-    return UISideMenuButton;
-}(UIComponent));
-var UISidebar = /** @class */ (function (_super) {
-    __extends(UISidebar, _super);
-    function UISidebar(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.backgrounds = [];
-        _this.scrollY = 0;
-        _this.elems = [];
-        _this.sprites = [];
-        _this.hoveredElem = null;
-        _this.scene = scene;
-        for (var i = 0; i < 30; i++) {
-            var background = new Phaser.GameObjects.Sprite(_this.scene, 0, 21 * 3 * i, "ui_sidebar_bg", 1);
+    }
+}
+class UISidebar extends UIContainer {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.backgrounds = [];
+        this.scrollY = 0;
+        this.elems = [];
+        this.sprites = [];
+        this.hoveredElem = null;
+        this.scene = scene;
+        for (let i = 0; i < 30; i++) {
+            let background = new Phaser.GameObjects.Sprite(this.scene, 0, 21 * 3 * i, "ui_sidebar_bg", 1);
             background.setScale(3);
             background.setOrigin(0, 0);
-            _this.backgrounds.push(background);
-            _this.list.push(background);
+            this.backgrounds.push(background);
+            this.list.push(background);
         }
-        _this.activeSpriteCursor = new Phaser.GameObjects.Sprite(_this.scene, 9, 9 + 21 * 3, "ui_sidebar_cursor");
-        _this.activeSpriteCursor.setScale(3);
-        _this.activeSpriteCursor.setOrigin(0);
-        _this.activeSpriteCursor.setVisible(false);
-        _this.list.push(_this.activeSpriteCursor);
-        _this.hoverSpriteCursor = new Phaser.GameObjects.Sprite(_this.scene, 3, 3, "ui_sidebar_cursor");
-        _this.hoverSpriteCursor.setScale(3);
-        _this.hoverSpriteCursor.setOrigin(0);
-        _this.hoverSpriteCursor.setAlpha(0.35);
-        _this.hoverSpriteCursor.setVisible(false);
-        _this.list.push(_this.hoverSpriteCursor);
+        this.activeSpriteCursor = new Phaser.GameObjects.Sprite(this.scene, 9, 9 + 21 * 3, "ui_sidebar_cursor");
+        this.activeSpriteCursor.setScale(3);
+        this.activeSpriteCursor.setOrigin(0);
+        this.activeSpriteCursor.setVisible(false);
+        this.list.push(this.activeSpriteCursor);
+        this.hoverSpriteCursor = new Phaser.GameObjects.Sprite(this.scene, 3, 3, "ui_sidebar_cursor");
+        this.hoverSpriteCursor.setScale(3);
+        this.hoverSpriteCursor.setOrigin(0);
+        this.hoverSpriteCursor.setAlpha(0.35);
+        this.hoverSpriteCursor.setVisible(false);
+        this.list.push(this.hoverSpriteCursor);
         // Bind the scroll wheel event
-        _this.onWheel = _this.onWheel.bind(_this);
-        document.documentElement.addEventListener("wheel", _this.onWheel);
-        _this.scene.events.on('destroy', function () { return document.documentElement.removeEventListener("wheel", _this.onWheel); });
-        return _this;
+        this.onWheel = this.onWheel.bind(this);
+        document.documentElement.addEventListener("wheel", this.onWheel);
+        this.scene.events.on('destroy', () => document.documentElement.removeEventListener("wheel", this.onWheel));
     }
-    UISidebar.prototype.onWheel = function (e) {
+    onWheel(e) {
         if (this.scene.ui.uiActive) {
-            var dir = (e.deltaY < 0 ? 1 : -1);
+            let dir = (e.deltaY < 0 ? 1 : -1);
             this.scrollY = clamp(this.scrollY + dir * 63, 0, -1000);
             this.scene.tweens.add({
                 targets: this,
@@ -1183,18 +1101,18 @@ var UISidebar = /** @class */ (function (_super) {
                 repeat: 0
             });
         }
-    };
-    UISidebar.prototype.mouseIntersects = function () {
+    }
+    mouseIntersects() {
         return (this.mousePos().x < 69);
-    };
-    UISidebar.prototype.update = function () {
-        var hovered = null;
+    }
+    update() {
+        let hovered = null;
         if (this.mouseIntersects()) {
             if (this.mousePos().x % 21 >= 4 && this.mousePos().y % 21 >= 4) {
-                var mousePos = this.mousePos();
-                var x = Math.floor(mousePos.x / 21);
-                var y = Math.floor(mousePos.y / 21) - 1;
-                for (var i = 0; i < this.sprites.length; i++) {
+                let mousePos = this.mousePos();
+                let x = Math.floor(mousePos.x / 21);
+                let y = Math.floor(mousePos.y / 21) - 1;
+                for (let i = 0; i < this.sprites.length; i++) {
                     if (Math.floor(this.sprites[i].x / 21 / 3) == x && Math.floor(this.sprites[i].y / 21 / 3) - 1 == y) {
                         hovered = this.sprites[i];
                         break;
@@ -1232,21 +1150,18 @@ var UISidebar = /** @class */ (function (_super) {
         }
         else
             this.hoverSpriteCursor.setVisible(false);
-    };
-    UISidebar.prototype.elemHover = function (x, y) { };
-    UISidebar.prototype.elemUnhover = function (x, y) { };
-    UISidebar.prototype.elemClick = function (x, y) { };
-    return UISidebar;
-}(UIContainer));
-var UISidebarToggle = /** @class */ (function (_super) {
-    __extends(UISidebarToggle, _super);
-    function UISidebarToggle(scene, x, y) {
-        var _this = _super.call(this, scene, x, y, "ui_button_sidebar_toggle") || this;
-        _this.scene = scene;
-        _this.setActive(true);
-        return _this;
     }
-    UISidebarToggle.prototype.update = function () {
+    elemHover(x, y) { }
+    elemUnhover(x, y) { }
+    elemClick(x, y) { }
+}
+class UISidebarToggle extends UIComponent {
+    constructor(scene, x, y) {
+        super(scene, x, y, "ui_button_sidebar_toggle");
+        this.scene = scene;
+        this.setActive(true);
+    }
+    update() {
         if (this.mouseIntersects() && this.mousePos().x >= 20) {
             this.setFrame(2 + (this.scene.ui.sidebarOpen ? 0 : 1));
             if (this.scene.i.mouseLeftPressed())
@@ -1256,244 +1171,226 @@ var UISidebarToggle = /** @class */ (function (_super) {
             this.setFrame(0 + (this.scene.ui.sidebarOpen ? 0 : 1));
         if (this.scene.i.keyPressed('F'))
             this.scene.ui.toggleSidebarOpen();
-    };
-    return UISidebarToggle;
-}(UIComponent));
-var UITileSelector = /** @class */ (function (_super) {
-    __extends(UITileSelector, _super);
-    function UITileSelector(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.tiles = [];
-        _this.scene = scene;
-        _this.background = new Phaser.GameObjects.Sprite(_this.scene, 0, 0, "ui_quick_selector");
-        _this.background.setScale(3, 3);
-        _this.background.setOrigin(0, 0);
-        _this.intersects.push(_this.background);
-        _this.add(_this.background);
-        _this.selectSprite = new Phaser.GameObjects.Sprite(_this.scene, 0, 0, "cursor");
-        _this.selectSprite.setScale(3, 3);
-        _this.selectSprite.setOrigin(0, 0);
-        _this.add(_this.selectSprite);
-        _this.positionSelect(0);
-        return _this;
     }
-    UITileSelector.prototype.positionSelect = function (slot) {
+}
+class UITileSelector extends UIContainer {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.tiles = [];
+        this.scene = scene;
+        this.background = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "ui_quick_selector");
+        this.background.setScale(3, 3);
+        this.background.setOrigin(0, 0);
+        this.intersects.push(this.background);
+        this.add(this.background);
+        this.selectSprite = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "cursor");
+        this.selectSprite.setScale(3, 3);
+        this.selectSprite.setOrigin(0, 0);
+        this.add(this.selectSprite);
+        this.positionSelect(0);
+    }
+    positionSelect(slot) {
         this.selectSprite.setPosition(12, 18 + slot * 60);
-    };
-    UITileSelector.prototype.update = function () {
+    }
+    update() {
         if (this.mouseIntersects() && this.scene.i.mouseLeftPressed()) {
-            var mousePos = this.mousePos();
+            let mousePos = this.mousePos();
             if (mousePos.x < 4 || mousePos.x > 4 + 16)
                 return;
             mousePos.y -= 6;
             if (mousePos.y % 20 > 16)
                 return;
-            var slot = Math.floor(mousePos.y / 20);
+            let slot = Math.floor(mousePos.y / 20);
             if (slot < 0 || slot >= this.tiles.length)
                 return;
             this.scene.architect.activeTileset = this.tiles[slot];
             this.positionSelect(slot);
         }
-    };
-    UITileSelector.prototype.addTile = function (tile) {
-        var pos = this.tiles.length;
+    }
+    addTile(tile) {
+        let pos = this.tiles.length;
         this.tiles.push(tile);
-        var spr = new Phaser.GameObjects.Sprite(this.scene, 12 - 22 * 2, 18 - 22 * 2 + pos * 60, "tileset_" + tile);
+        let spr = new Phaser.GameObjects.Sprite(this.scene, 12 - 22 * 2, 18 - 22 * 2 + pos * 60, "tileset_" + tile);
         spr.setOrigin(0, 0);
         spr.setCrop(22, 22, 24, 24);
         spr.setScale(2);
         this.add(spr);
         this.sendToBack(spr);
         this.sendToBack(this.background);
-    };
-    return UITileSelector;
-}(UIContainer));
-var UITileSidebar = /** @class */ (function (_super) {
-    __extends(UITileSidebar, _super);
-    function UITileSidebar(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.walls = [];
-        _this.grounds = [];
-        _this.overlays = [];
-        var add_wall = new Phaser.GameObjects.Sprite(_this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_browse");
+    }
+}
+class UITileSidebar extends UISidebar {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.walls = [];
+        this.grounds = [];
+        this.overlays = [];
+        let add_wall = new Phaser.GameObjects.Sprite(this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_browse");
         add_wall.setName("add_wall");
         add_wall.setScale(3);
         add_wall.setOrigin(0, 0);
-        _this.list.push(add_wall);
-        _this.sprites.push(add_wall);
-        for (var _i = 0, WALLS_2 = WALLS; _i < WALLS_2.length; _i++) {
-            var tileset = WALLS_2[_i];
-            _this.addWall(tileset.key);
+        this.list.push(add_wall);
+        this.sprites.push(add_wall);
+        for (let tileset of WALLS) {
+            this.addWall(tileset.key);
         }
-        var add_ground = new Phaser.GameObjects.Sprite(_this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_browse");
+        let add_ground = new Phaser.GameObjects.Sprite(this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_browse");
         add_ground.setName("add_ground");
         add_ground.setScale(3);
         add_ground.setOrigin(0, 0);
-        _this.list.push(add_ground);
-        _this.sprites.push(add_ground);
-        for (var _a = 0, GROUNDS_2 = GROUNDS; _a < GROUNDS_2.length; _a++) {
-            var tileset = GROUNDS_2[_a];
-            _this.addGround(tileset.key);
+        this.list.push(add_ground);
+        this.sprites.push(add_ground);
+        for (let tileset of GROUNDS) {
+            this.addGround(tileset.key);
         }
-        var add_overlay = new Phaser.GameObjects.Sprite(_this.scene, 9 + x * 21 * 3, 9 + 9 * 21 * 3, "ui_sidebar_browse");
+        let add_overlay = new Phaser.GameObjects.Sprite(this.scene, 9 + x * 21 * 3, 9 + 9 * 21 * 3, "ui_sidebar_browse");
         add_overlay.setName("add_overlay");
         add_overlay.setScale(3);
         add_overlay.setOrigin(0, 0);
-        _this.list.push(add_overlay);
-        _this.sprites.push(add_overlay);
-        for (var _b = 0, OVERLAYS_2 = OVERLAYS; _b < OVERLAYS_2.length; _b++) {
-            var tileset = OVERLAYS_2[_b];
-            _this.addOverlay(tileset.key);
+        this.list.push(add_overlay);
+        this.sprites.push(add_overlay);
+        for (let tileset of OVERLAYS) {
+            this.addOverlay(tileset.key);
         }
-        for (var i = 0; i < 12; i++) {
+        for (let i = 0; i < 12; i++) {
             if (i % 4 != 0)
-                _this.backgrounds[i].setFrame(0);
+                this.backgrounds[i].setFrame(0);
         }
-        return _this;
     }
-    UITileSidebar.prototype.elemClick = function (x, y) {
+    elemClick(x, y) {
         if (y < 4) {
             this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.walls[x + y * 3]];
-            this.scene.architect.activeLayer = 1 /* WALL */;
+            this.scene.architect.activeLayer = 1 /* wall */;
         }
         else if (y < 8) {
             this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.grounds[x + (y - 4) * 3]];
-            this.scene.architect.activeLayer = 0 /* GROUND */;
+            this.scene.architect.activeLayer = 0 /* floor */;
         }
         else {
             this.scene.architect.activeTileset = this.scene.map.manager.indexes[this.overlays[x + (y - 8) * 3]];
-            this.scene.architect.activeLayer = 2 /* OVERLAY */;
+            this.scene.architect.activeLayer = 2 /* overlay */;
         }
-    };
-    UITileSidebar.prototype.addWall = function (tileset) {
+    }
+    addWall(tileset) {
         this.addTilesetSprite(tileset, this.walls.length % 3, Math.floor(this.walls.length / 3) + 1, 17);
         this.getByName("add_wall").x = 9 + ((this.walls.length + 1) % 3 * 21 * 3);
         this.getByName("add_wall").y = 9 + (Math.floor((this.walls.length + 1) / 3 + 1) * 21 * 3);
         this.walls.push(tileset);
-    };
-    UITileSidebar.prototype.addGround = function (tileset) {
+    }
+    addGround(tileset) {
         this.addTilesetSprite(tileset, this.grounds.length % 3, Math.floor(this.grounds.length / 3) + 5, 13);
         this.getByName("add_ground").x = 9 + ((this.grounds.length + 1) % 3 * 21 * 3);
         this.getByName("add_ground").y = 9 + (Math.floor((this.grounds.length + 1) / 3 + 5) * 21 * 3);
         this.grounds.push(tileset);
-    };
-    UITileSidebar.prototype.addOverlay = function (tileset) {
+    }
+    addOverlay(tileset) {
         this.addTilesetSprite(tileset, this.overlays.length % 3, Math.floor(this.overlays.length / 3) + 9, 33);
         this.getByName("add_overlay").x = 9 + ((this.overlays.length + 1) % 3 * 21 * 3);
         this.getByName("add_overlay").y = 9 + (Math.floor((this.overlays.length + 1) / 3 + 9) * 21 * 3);
         this.overlays.push(tileset);
-    };
-    UITileSidebar.prototype.addTilesetSprite = function (key, x, y, frame) {
-        var spr = new Phaser.GameObjects.Sprite(this.scene, 12 + x * 21 * 3, 12 + y * 21 * 3, key, frame);
+    }
+    addTilesetSprite(key, x, y, frame) {
+        let spr = new Phaser.GameObjects.Sprite(this.scene, 12 + x * 21 * 3, 12 + y * 21 * 3, key, frame);
         spr.setOrigin(0, 0);
         spr.setScale(3);
         this.sprites.push(spr);
         this.list.push(spr);
-        var spr2 = new Phaser.GameObjects.Sprite(this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_overlay");
+        let spr2 = new Phaser.GameObjects.Sprite(this.scene, 9 + x * 21 * 3, 9 + y * 21 * 3, "ui_sidebar_overlay");
         spr2.setScale(3);
         spr2.setOrigin(0, 0);
         this.list.push(spr2);
         this.bringToTop(this.hoverSpriteCursor);
         this.bringToTop(this.activeSpriteCursor);
-    };
-    return UITileSidebar;
-}(UISidebar));
-var UITokenProps = /** @class */ (function (_super) {
-    __extends(UITokenProps, _super);
-    function UITokenProps(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        var dims = new Vec2(300, 400);
-        var e = new Phaser.GameObjects.Sprite(scene, 0, 0, "ui_background_9x", 0);
+    }
+}
+class UITokenProps extends UIContainer {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        let dims = new Vec2(300, 400);
+        let e = new Phaser.GameObjects.Sprite(scene, 0, 0, "ui_background_9x", 0);
         e.setScale(3, 3);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, 8 * 3, 0, "ui_background_9x", 1);
         e.setScale((dims.x - 16 * 3) / 8, 3);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, dims.x - 8 * 3, 0, "ui_background_9x", 2);
         e.setScale(3);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, 0, 8 * 3, "ui_background_9x", 3);
         e.setScale(3, (dims.y - 16 * 3) / 8);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, 8 * 3, 8 * 3, "ui_background_9x", 4);
         e.setScale((dims.x - 16 * 3) / 8, (dims.y - 16 * 3) / 8);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, dims.x - 8 * 3, 8 * 3, "ui_background_9x", 5);
         e.setScale(3, (dims.y - 16 * 3) / 8);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, 0, (dims.y - 8 * 3), "ui_background_9x", 6);
         e.setScale(3);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, 8 * 3, (dims.y - 8 * 3), "ui_background_9x", 7);
         e.setScale((dims.x - 16 * 3) / 8, 3);
-        _this.add(e);
+        this.add(e);
         e = new Phaser.GameObjects.Sprite(scene, dims.x - 8 * 3, (dims.y - 8 * 3), "ui_background_9x", 8);
         e.setScale(3);
-        _this.add(e);
-        _this.list.forEach(function (e) { return e.setOrigin(0, 0); });
-        return _this;
+        this.add(e);
+        this.list.forEach(e => e.setOrigin(0, 0));
     }
-    return UITokenProps;
-}(UIContainer));
-var UITokenSelector = /** @class */ (function (_super) {
-    __extends(UITokenSelector, _super);
-    function UITokenSelector(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.tokens = [];
-        _this.scene = scene;
-        _this.background = new Phaser.GameObjects.Sprite(_this.scene, 0, 0, "ui_quick_selector");
-        _this.background.setScale(3, 3);
-        _this.background.setOrigin(0, 0);
-        _this.intersects.push(_this.background);
-        _this.add(_this.background);
-        _this.selectSprite = new Phaser.GameObjects.Sprite(_this.scene, 0, 0, "cursor");
-        _this.selectSprite.setScale(3, 3);
-        _this.selectSprite.setOrigin(0, 0);
-        _this.add(_this.selectSprite);
-        _this.positionSelect(0);
-        return _this;
+}
+class UITokenSelector extends UIContainer {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.tokens = [];
+        this.scene = scene;
+        this.background = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "ui_quick_selector");
+        this.background.setScale(3, 3);
+        this.background.setOrigin(0, 0);
+        this.intersects.push(this.background);
+        this.add(this.background);
+        this.selectSprite = new Phaser.GameObjects.Sprite(this.scene, 0, 0, "cursor");
+        this.selectSprite.setScale(3, 3);
+        this.selectSprite.setOrigin(0, 0);
+        this.add(this.selectSprite);
+        this.positionSelect(0);
     }
-    UITokenSelector.prototype.positionSelect = function (slot) {
+    positionSelect(slot) {
         this.selectSprite.setPosition(12, 18 + slot * 60);
-    };
-    UITokenSelector.prototype.update = function () {
+    }
+    update() {
         if (this.mouseIntersects() && this.scene.i.mouseLeftPressed()) {
-            var mousePos = this.mousePos();
+            let mousePos = this.mousePos();
             if (mousePos.x < 4 || mousePos.x > 4 + 16)
                 return;
             mousePos.y -= 6;
             if (mousePos.y % 20 > 16)
                 return;
-            var slot = Math.floor(mousePos.y / 20);
+            let slot = Math.floor(mousePos.y / 20);
             if (slot < 0 || slot >= this.tokens.length)
                 return;
             this.scene.token.selectedTokenType = this.tokens[slot];
             this.positionSelect(slot);
         }
-    };
-    UITokenSelector.prototype.addToken = function (sprite) {
-        var pos = this.tokens.length;
+    }
+    addToken(sprite) {
+        let pos = this.tokens.length;
         this.tokens.push(sprite);
-        var spr = new Phaser.GameObjects.Sprite(this.scene, 12 - 3, 18 - 3 + pos * 60, sprite);
+        let spr = new Phaser.GameObjects.Sprite(this.scene, 12 - 3, 18 - 3 + pos * 60, sprite);
         spr.setOrigin(0, 0);
         spr.setScale(3);
         this.add(spr);
         this.sendToBack(spr);
         this.sendToBack(this.background);
-    };
-    return UITokenSelector;
-}(UIContainer));
-var UITokenSidebar = /** @class */ (function (_super) {
-    __extends(UITokenSidebar, _super);
-    function UITokenSidebar(scene, x, y) {
-        var _this = _super.call(this, scene, x, y) || this;
-        _this.spinTimer = 0;
-        _this.cursorMode = new UIComponent(scene, 15 - 2 / 3, 1, "ui_button_select_cursor");
-        _this.add(_this.cursorMode);
-        return _this;
     }
-    UITokenSidebar.prototype.update = function () {
-        _super.prototype.update.call(this);
+}
+class UITokenSidebar extends UISidebar {
+    constructor(scene, x, y) {
+        super(scene, x, y);
+        this.spinTimer = 0;
+        this.cursorMode = new UIComponent(scene, 15 - 2 / 3, 1, "ui_button_select_cursor");
+        this.add(this.cursorMode);
+    }
+    update() {
+        super.update();
         if (this.scene.token.selectedTokenType == "")
             this.cursorMode.setFrame(0);
         else
@@ -1505,8 +1402,8 @@ var UITokenSidebar = /** @class */ (function (_super) {
         }
         if (this.scene.i.keyPressed('S'))
             this.toggleSelectMode(this.scene.token.selectedTokenType != "");
-    };
-    UITokenSidebar.prototype.toggleSelectMode = function (select) {
+    }
+    toggleSelectMode(select) {
         if (select) {
             this.scene.token.selectedTokenType = "";
             this.activeSpriteCursor.setVisible(false);
@@ -1515,43 +1412,42 @@ var UITokenSidebar = /** @class */ (function (_super) {
             this.scene.token.selectedTokenType = this.elems[this.lastSelectedToken];
             this.activeSpriteCursor.setVisible(true);
         }
-    };
-    UITokenSidebar.prototype.elemHover = function (x, y) {
-        var hoveredToken = this.sprites[x + y * 3];
+    }
+    elemHover(x, y) {
+        let hoveredToken = this.sprites[x + y * 3];
         this.spinTimer++;
         if (this.spinTimer > 20) {
-            var frame = hoveredToken.getFrame() + 1;
+            let frame = hoveredToken.getFrame() + 1;
             frame %= hoveredToken.frameCount();
             hoveredToken.setFrame(frame);
             this.spinTimer = 0;
         }
-    };
-    UITokenSidebar.prototype.elemUnhover = function (x, y) {
-        this.sprites.forEach(function (t) { return t.setFrame(0); });
-    };
-    UITokenSidebar.prototype.elemClick = function (x, y) {
+    }
+    elemUnhover(x, y) {
+        this.sprites.forEach(t => t.setFrame(0));
+    }
+    elemClick(x, y) {
         this.lastSelectedToken = x + y * 3;
         this.scene.token.selectedTokenType = this.elems[x + y * 3];
-    };
-    UITokenSidebar.prototype.addToken = function (sprite) {
-        var p = this.elems.length;
-        var x = p % 3;
-        var y = Math.floor(p / 3) + 1;
+    }
+    addToken(sprite) {
+        let p = this.elems.length;
+        let x = p % 3;
+        let y = Math.floor(p / 3) + 1;
         this.elems.push(sprite);
         if (x == 0)
             this.backgrounds[y].setFrame(0);
-        var token = new Token(this.scene, 0, 0, sprite);
+        let token = new Token(this.scene, 0, 0, sprite);
         Phaser.GameObjects.Sprite.prototype.setPosition.call(token, 12 + x * 21 * 3, 12 + y * 21 * 3);
         token.setScale(3 / 4);
         this.sprites.push(token);
         this.list.push(token);
         this.bringToTop(this.activeSpriteCursor);
         this.bringToTop(this.hoverSpriteCursor);
-    };
-    return UITokenSidebar;
-}(UISidebar));
-var ArchitectMode = /** @class */ (function () {
-    function ArchitectMode(scene) {
+    }
+}
+class ArchitectMode {
+    constructor(scene) {
         this.active = false;
         this.primitives = [];
         this.startTilePos = new Vec2();
@@ -1559,7 +1455,7 @@ var ArchitectMode = /** @class */ (function () {
         this.pointerDown = false;
         this.pointerPrimaryDown = false;
         this.activeTileset = 0;
-        this.activeLayer = 1 /* WALL */;
+        this.activeLayer = 1 /* wall */;
         this.manipulated = [];
         this.scene = scene;
         // Create cursor hover sprite
@@ -1568,13 +1464,13 @@ var ArchitectMode = /** @class */ (function () {
         this.cursor.setDepth(1000);
         this.cursor.setOrigin(0, 0);
     }
-    ArchitectMode.prototype.update = function () {
+    update() {
         this.active = true;
         this.cursor.setVisible(true);
-        var selectedTilePos = new Vec2(Math.floor(this.scene.world.cursorWorld.x / 64), Math.floor(this.scene.world.cursorWorld.y / 64));
+        let selectedTilePos = new Vec2(Math.floor(this.scene.world.cursorWorld.x / 64), Math.floor(this.scene.world.cursorWorld.y / 64));
         this.cursor.setPosition(selectedTilePos.x * 64, selectedTilePos.y * 64);
         this.cursor.setVisible((selectedTilePos.x >= 0 && selectedTilePos.y >= 0 &&
-            selectedTilePos.x < this.scene.map.dimensions.x && selectedTilePos.y < this.scene.map.dimensions.y));
+            selectedTilePos.x < this.scene.map.size.x && selectedTilePos.y < this.scene.map.size.y));
         // Place Tiles
         switch (this.placeMode) {
             case "brush": {
@@ -1613,22 +1509,22 @@ var ArchitectMode = /** @class */ (function () {
             this.pointerDown = false;
             this.pointerPrimaryDown = false;
         }
-    };
-    ArchitectMode.prototype.drawLine = function (selectedTilePos) {
+    }
+    drawLine(selectedTilePos) {
         if (this.scene.input.mousePointer.leftButtonDown() || this.scene.input.mousePointer.rightButtonDown()) {
             if (!this.pointerDown)
                 this.startTilePos = selectedTilePos;
-            var a = new Vec2(this.startTilePos.x, this.startTilePos.y);
-            var b = new Vec2(selectedTilePos.x, selectedTilePos.y);
+            let a = new Vec2(this.startTilePos.x, this.startTilePos.y);
+            let b = new Vec2(selectedTilePos.x, selectedTilePos.y);
             if (Math.abs(b.x - a.x) > Math.abs(b.y - a.y))
                 b.y = a.y;
             else
                 b.x = a.x;
             this.cursor.setPosition(b.x * 64, b.y * 64);
-            this.primitives.forEach(function (v) { return v.destroy(); });
+            this.primitives.forEach((v) => v.destroy());
             this.primitives = [];
             this.primitives.push(this.scene.add.line(0, 0, a.x + 0.5, a.y + 0.5, b.x + 0.5, b.y + 0.5, 0xffffff, 1));
-            this.primitives.forEach(function (v) {
+            this.primitives.forEach((v) => {
                 v.setOrigin(0, 0);
                 v.setScale(64, 64);
                 v.setLineWidth(0.03);
@@ -1640,14 +1536,14 @@ var ArchitectMode = /** @class */ (function () {
             this.primitives[1].setAlpha(0.5);
         }
         else if (!this.scene.input.mousePointer.leftButtonDown() && !this.scene.input.mousePointer.rightButtonDown() && this.pointerDown) {
-            var a = new Vec2(this.startTilePos.x * 64, this.startTilePos.y * 64);
-            var b = new Vec2(selectedTilePos.x * 64, selectedTilePos.y * 64);
+            let a = new Vec2(this.startTilePos.x * 64, this.startTilePos.y * 64);
+            let b = new Vec2(selectedTilePos.x * 64, selectedTilePos.y * 64);
             if (Math.abs(b.x - a.x) > Math.abs(b.y - a.y))
                 b.y = a.y;
             else
                 b.x = a.x;
-            var change = new Vec2(b.x - a.x, b.y - a.y);
-            var normalizeFactor = Math.sqrt(change.x * change.x + change.y * change.y);
+            let change = new Vec2(b.x - a.x, b.y - a.y);
+            let normalizeFactor = Math.sqrt(change.x * change.x + change.y * change.y);
             change.x /= normalizeFactor;
             change.y /= normalizeFactor;
             while (Math.abs(b.x - a.x) >= 1 || Math.abs(b.y - a.y) >= 1) {
@@ -1656,24 +1552,24 @@ var ArchitectMode = /** @class */ (function () {
                 a.y += change.y;
             }
             this.placeTileAndPushManip(new Vec2(b.x / 64, b.y / 64), this.pointerPrimaryDown);
-            this.primitives.forEach(function (v) { return v.destroy(); });
+            this.primitives.forEach((v) => v.destroy());
             this.primitives = [];
         }
-    };
-    ArchitectMode.prototype.drawRect = function (selectedTilePos) {
+    }
+    drawRect(selectedTilePos) {
         if (this.scene.input.mousePointer.leftButtonDown() || this.scene.input.mousePointer.rightButtonDown()) {
             if (!this.pointerDown)
                 this.startTilePos = selectedTilePos;
-            var a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
-            var b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
-            this.primitives.forEach(function (v) { return v.destroy(); });
+            let a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
+            let b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
+            this.primitives.forEach((v) => v.destroy());
             this.primitives = [];
-            var fac = 0.03;
+            const fac = 0.03;
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, a.y + fac, b.x + 1 - fac, a.y + fac, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, a.y + fac / 2, a.x + fac, b.y + 1 - fac / 2, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, b.y + 1 - fac, b.x + 1 - fac, b.y + 1 - fac, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, b.x + 1 - fac, a.y + fac / 2, b.x + 1 - fac, b.y + 1 - fac / 2, 0xffffff, 1));
-            this.primitives.forEach(function (v) {
+            this.primitives.forEach((v) => {
                 v.setOrigin(0, 0);
                 v.setScale(64, 64);
                 v.setLineWidth(0.03);
@@ -1681,24 +1577,24 @@ var ArchitectMode = /** @class */ (function () {
             });
         }
         else if (!this.scene.input.mousePointer.leftButtonDown() && !this.scene.input.mousePointer.rightButtonDown() && this.pointerDown) {
-            var a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
-            var b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
-            for (var i = a.x; i <= b.x; i++) {
-                for (var j = a.y; j <= b.y; j++) {
+            let a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
+            let b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
+            for (let i = a.x; i <= b.x; i++) {
+                for (let j = a.y; j <= b.y; j++) {
                     this.placeTileAndPushManip(new Vec2(i, j), this.pointerPrimaryDown);
                 }
             }
-            this.primitives.forEach(function (v) { return v.destroy(); });
+            this.primitives.forEach((v) => v.destroy());
             this.primitives = [];
         }
-    };
-    ArchitectMode.prototype.drawBrush = function (selectedTilePos) {
+    }
+    drawBrush(selectedTilePos) {
         if (this.scene.input.mousePointer.leftButtonDown() || this.scene.input.mousePointer.rightButtonDown()) {
-            var change = new Vec2(this.scene.world.cursorWorld.x - this.scene.world.lastCursorWorld.x, this.scene.world.cursorWorld.y - this.scene.world.lastCursorWorld.y);
-            var normalizeFactor = Math.sqrt(change.x * change.x + change.y * change.y);
+            let change = new Vec2(this.scene.world.cursorWorld.x - this.scene.world.lastCursorWorld.x, this.scene.world.cursorWorld.y - this.scene.world.lastCursorWorld.y);
+            let normalizeFactor = Math.sqrt(change.x * change.x + change.y * change.y);
             change.x /= normalizeFactor;
             change.y /= normalizeFactor;
-            var place = new Vec2(this.scene.world.lastCursorWorld.x, this.scene.world.lastCursorWorld.y);
+            let place = new Vec2(this.scene.world.lastCursorWorld.x, this.scene.world.lastCursorWorld.y);
             while (Math.abs(this.scene.world.cursorWorld.x - place.x) >= 1 || Math.abs(this.scene.world.cursorWorld.y - place.y) >= 1) {
                 this.placeTileAndPushManip(new Vec2(Math.floor(place.x / 64), Math.floor(place.y / 64)), this.scene.input.mousePointer.leftButtonDown());
                 place.x += change.x;
@@ -1706,32 +1602,30 @@ var ArchitectMode = /** @class */ (function () {
             }
             this.placeTileAndPushManip(new Vec2(selectedTilePos.x, selectedTilePos.y), this.scene.input.mousePointer.leftButtonDown());
         }
-    };
-    ArchitectMode.prototype.placeTileAndPushManip = function (manipPos, solid) {
-        var tile = solid ? this.activeTileset : -1;
-        var layer = (tile == -1 && this.activeLayer == 0 /* GROUND */) ? 1 /* WALL */ : this.activeLayer;
-        var lastTile = this.scene.map.getTile(manipPos.x, manipPos.y, layer);
+    }
+    placeTileAndPushManip(manipPos, solid) {
+        let tile = solid ? this.activeTileset : -1;
+        let layer = (tile == -1 && this.activeLayer == 0 /* floor */) ? 1 /* wall */ : this.activeLayer;
+        let lastTile = this.scene.map.getTileset(layer, manipPos.x, manipPos.y);
         if (tile == lastTile)
             return;
-        this.scene.map.setTile(manipPos.x, manipPos.y, tile, layer);
+        this.scene.map.setTile(layer, tile, manipPos.x, manipPos.y);
         this.manipulated.push({
             pos: manipPos,
             layer: layer,
             lastTile: lastTile,
             tile: tile
         });
-    };
-    ArchitectMode.prototype.cleanup = function () {
+    }
+    cleanup() {
         if (!this.active)
             return;
         this.active = false;
         this.cursor.setVisible(false);
-    };
-    return ArchitectMode;
-}());
-var TokenMode = /** @class */ (function () {
-    function TokenMode(scene) {
-        var _this = this;
+    }
+}
+class TokenMode {
+    constructor(scene) {
         this.active = false;
         this.primitives = [];
         this.selectedTokenType = "";
@@ -1744,7 +1638,7 @@ var TokenMode = /** @class */ (function () {
         this.scene = scene;
         this.onWheel = this.onWheel.bind(this);
         document.documentElement.addEventListener("wheel", this.onWheel);
-        this.scene.events.on('destroy', function () { return document.documentElement.removeEventListener("wheel", _this.onWheel); });
+        this.scene.events.on('destroy', () => document.documentElement.removeEventListener("wheel", this.onWheel));
         // Create cursor hover sprite
         this.cursor = this.scene.add.sprite(0, 0, "cursor");
         this.cursor.setScale(4, 4);
@@ -1756,21 +1650,21 @@ var TokenMode = /** @class */ (function () {
         this.tokenPreview.setVisible(false);
         this.tokenPreview.setAlpha(0.2);
     }
-    TokenMode.prototype.onWheel = function (e) {
+    onWheel(e) {
         if (this.movingTokens) {
-            var dir_1 = e.deltaY > 0 ? 1 : -1;
-            this.selectedTokens.forEach(function (token) {
-                var frame = token.getFrame() + dir_1;
+            let dir = e.deltaY > 0 ? 1 : -1;
+            this.selectedTokens.forEach((token) => {
+                let frame = token.getFrame() + dir;
                 if (frame < 0)
                     frame += token.frameCount();
                 frame %= token.frameCount();
                 token.setFrame(frame);
             });
         }
-    };
-    TokenMode.prototype.update = function () {
+    }
+    update() {
         this.active = true;
-        var selectedTilePos = new Vec2(Math.floor(this.scene.world.cursorWorld.x / 64), Math.floor(this.scene.world.cursorWorld.y / 64));
+        let selectedTilePos = new Vec2(Math.floor(this.scene.world.cursorWorld.x / 64), Math.floor(this.scene.world.cursorWorld.y / 64));
         if (this.movingTokens)
             this.moving();
         if (!this.movingTokens)
@@ -1789,8 +1683,8 @@ var TokenMode = /** @class */ (function () {
             this.cursor.setVisible(this.hoveredToken == null);
         if (this.tokenPreview.sprite.texture.key != this.selectedTokenType)
             this.tokenPreview.setTexture(this.selectedTokenType);
-    };
-    TokenMode.prototype.tokenMoveControls = function () {
+    }
+    tokenMoveControls() {
         if (this.scene.i.keyPressed('UP')) {
             this.moveToken(0, -16, 2);
         }
@@ -1803,26 +1697,25 @@ var TokenMode = /** @class */ (function () {
         if (this.scene.i.keyPressed('RIGHT')) {
             this.moveToken(16, 0, 3);
         }
-    };
-    TokenMode.prototype.selectedIncludes = function (t) {
-        for (var _i = 0, _a = this.selectedTokens; _i < _a.length; _i++) {
-            var token = _a[_i];
+    }
+    selectedIncludes(t) {
+        for (let token of this.selectedTokens) {
             if (token == t)
                 return true;
         }
         return false;
-    };
-    TokenMode.prototype.moveToken = function (x, y, frame) {
-        var prevSerialized = [];
-        this.selectedTokens.forEach(function (token) {
+    }
+    moveToken(x, y, frame) {
+        let prevSerialized = [];
+        this.selectedTokens.forEach((token) => {
             prevSerialized.push(token.serialize());
             token.x += x * 4;
             token.y += y * 4;
             token.setFrame(frame);
         });
-        var identical = true;
-        var currSerialized = [];
-        for (var s = 0; s < prevSerialized.length; s++) {
+        let identical = true;
+        let currSerialized = [];
+        for (let s = 0; s < prevSerialized.length; s++) {
             currSerialized.push(this.selectedTokens[s].serialize());
             if (prevSerialized[s] != currSerialized[s])
                 identical = false;
@@ -1830,26 +1723,23 @@ var TokenMode = /** @class */ (function () {
         if (!identical) {
             this.scene.history.push("token_modify", { old: prevSerialized, new: currSerialized });
         }
-    };
-    TokenMode.prototype.selecting = function () {
-        var _this = this;
-        var cursor = this.scene.world.cursorWorld;
-        var clickedAddedThisFrame = false;
+    }
+    selecting() {
+        const cursor = this.scene.world.cursorWorld;
+        let clickedAddedThisFrame = false;
         // Find the currently hovered token, and remove all outlines. 
         this.hoveredToken = null;
-        for (var i = this.scene.tokens.length - 1; i >= 0; i--) {
-            var token = this.scene.tokens[i];
+        for (let i = this.scene.tokens.length - 1; i >= 0; i--) {
+            let token = this.scene.tokens[i];
             if (cursor.x >= token.x && cursor.y >= token.y && cursor.x <= token.x + token.width - 8 && cursor.y <= token.y + token.height - 8) {
                 this.hoveredToken = token;
                 break;
             }
         }
         // Apply outline to hovered token, remove it from non-hovered tokens
-        for (var _i = 0, _a = this.scene.tokens; _i < _a.length; _i++) {
-            var token = _a[_i];
+        for (let token of this.scene.tokens)
             if (token != this.hoveredToken)
                 token.setHovered(false);
-        }
         if (this.hoveredToken != null)
             this.hoveredToken.setHovered(true);
         if (this.scene.i.mouseLeftPressed()) {
@@ -1860,13 +1750,13 @@ var TokenMode = /** @class */ (function () {
             else if (this.hoveredToken == null) {
                 // Create a new token and move
                 if (this.selectedTokenType != "") {
-                    var token = this.createToken();
+                    let token = this.createToken();
                     if (this.scene.i.keyDown('CTRL')) {
                         if (!this.selectedIncludes(token))
                             this.selectedTokens.push(token);
                     }
                     else {
-                        this.selectedTokens.forEach(function (t) { return t.setSelected(false); });
+                        this.selectedTokens.forEach(t => t.setSelected(false));
                         this.selectedTokens = [token];
                     }
                     this.clickedLastFrame = true;
@@ -1890,7 +1780,7 @@ var TokenMode = /** @class */ (function () {
                     this.startMovingTokens();
                 }
                 else {
-                    this.selectedTokens.forEach(function (t) { return t.setSelected(false); });
+                    this.selectedTokens.forEach(t => t.setSelected(false));
                     this.selectedTokens = [this.hoveredToken];
                     this.clickedLastFrame = true;
                     clickedAddedThisFrame = true;
@@ -1902,28 +1792,25 @@ var TokenMode = /** @class */ (function () {
         if (this.scene.i.mouseLeftReleased()) {
             // Deselect current token if CTRL is down, or deselect all and select current token.
             if (this.startTilePos != null) {
-                this.primitives.forEach(function (v) { return v.destroy(); });
+                this.primitives.forEach((v) => v.destroy());
                 this.primitives = [];
-                var selectedTilePos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
-                var a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
-                var b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
+                let selectedTilePos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
+                let a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
+                let b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
                 if (!this.scene.i.keyDown('CTRL')) {
-                    for (var _b = 0, _c = this.selectedTokens; _b < _c.length; _b++) {
-                        var s = _c[_b];
+                    for (let s of this.selectedTokens)
                         s.setSelected(false);
-                    }
                     this.selectedTokens = [];
                 }
-                for (var _d = 0, _e = this.scene.tokens; _d < _e.length; _d++) {
-                    var token = _e[_d];
-                    var tokenTilePos = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64));
+                for (let token of this.scene.tokens) {
+                    let tokenTilePos = new Vec2(Math.floor(token.x / 64), Math.floor(token.y / 64));
                     if (tokenTilePos.x >= a.x && tokenTilePos.y >= a.y && tokenTilePos.x <= b.x && tokenTilePos.y <= b.y) {
-                        var selected = this.scene.i.keyDown('CTRL') ? !this.selectedIncludes(token) : true;
+                        let selected = this.scene.i.keyDown('CTRL') ? !this.selectedIncludes(token) : true;
                         token.setSelected(selected);
                         if (selected && !this.selectedIncludes(token))
                             this.selectedTokens.push(token);
                         else if (!selected && this.selectedIncludes(token)) {
-                            for (var i = 0; i < this.selectedTokens.length; i++) {
+                            for (let i = 0; i < this.selectedTokens.length; i++) {
                                 if (this.selectedTokens[i] == token)
                                     this.selectedTokens.splice(i, 1);
                             }
@@ -1936,7 +1823,7 @@ var TokenMode = /** @class */ (function () {
             }
             else if (!this.movedTokens && !this.clickedLastFrame && this.selectedIncludes(this.hoveredToken)) {
                 if (this.scene.i.keyDown('CTRL')) {
-                    for (var i = 0; i < this.selectedTokens.length; i++) {
+                    for (let i = 0; i < this.selectedTokens.length; i++) {
                         if (this.selectedTokens[i] == this.hoveredToken) {
                             this.selectedTokens[i].setSelected(false);
                             this.selectedTokens.splice(i, 1);
@@ -1945,7 +1832,7 @@ var TokenMode = /** @class */ (function () {
                     }
                 }
                 else {
-                    this.selectedTokens.forEach(function (t) { return t.setSelected(false); });
+                    this.selectedTokens.forEach(t => t.setSelected(false));
                     this.selectedTokens = [this.hoveredToken];
                     this.hoveredToken.setSelected(true);
                     this.startMovingTokens();
@@ -1954,57 +1841,57 @@ var TokenMode = /** @class */ (function () {
             this.movedTokens = false;
         }
         if (this.scene.i.keyDown('DELETE') && this.selectedTokens.length > 0) {
-            var serializedData_1 = [];
-            this.selectedTokens.forEach(function (t) {
-                for (var i = 0; i < _this.scene.tokens.length; i++) {
-                    if (_this.scene.tokens[i] == t) {
-                        _this.scene.tokens.splice(i, 1);
+            let serializedData = [];
+            this.selectedTokens.forEach(t => {
+                for (let i = 0; i < this.scene.tokens.length; i++) {
+                    if (this.scene.tokens[i] == t) {
+                        this.scene.tokens.splice(i, 1);
                         break;
                     }
                 }
-                serializedData_1.push(t.serialize());
-                if (_this.hoveredToken == t)
-                    _this.hoveredToken = null;
+                serializedData.push(t.serialize());
+                if (this.hoveredToken == t)
+                    this.hoveredToken = null;
                 t.destroy();
             });
             this.selectedTokens = [];
-            this.scene.history.push("token_delete", { data: serializedData_1 });
+            this.scene.history.push("token_delete", { data: serializedData });
         }
         if (!clickedAddedThisFrame)
             this.clickedLastFrame = null;
         if (this.scene.i.mouseLeftDown())
             this.updateRectangleSelect();
-    };
-    TokenMode.prototype.updateRectangleSelect = function () {
-        var cursor = this.scene.world.cursorWorld;
-        var selectedTilePos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
-        this.primitives.forEach(function (v) { return v.destroy(); });
+    }
+    updateRectangleSelect() {
+        const cursor = this.scene.world.cursorWorld;
+        let selectedTilePos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
+        this.primitives.forEach((v) => v.destroy());
         this.primitives = [];
         if (this.startTilePos != null) {
-            var a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
-            var b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
-            var fac = 0.03;
+            let a = new Vec2(Math.min(this.startTilePos.x, selectedTilePos.x), Math.min(this.startTilePos.y, selectedTilePos.y));
+            let b = new Vec2(Math.max(this.startTilePos.x, selectedTilePos.x), Math.max(this.startTilePos.y, selectedTilePos.y));
+            const fac = 0.03;
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, a.y + fac, b.x + 1 - fac, a.y + fac, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, a.y + fac / 2, a.x + fac, b.y + 1 - fac / 2, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, a.x + fac, b.y + 1 - fac, b.x + 1 - fac, b.y + 1 - fac, 0xffffff, 1));
             this.primitives.push(this.scene.add.line(0, 0, b.x + 1 - fac, a.y + fac / 2, b.x + 1 - fac, b.y + 1 - fac / 2, 0xffffff, 1));
-            this.primitives.forEach(function (v) {
+            this.primitives.forEach((v) => {
                 v.setOrigin(0, 0);
                 v.setScale(64, 64);
                 v.setLineWidth(0.03);
                 v.setDepth(300);
             });
         }
-    };
-    TokenMode.prototype.moving = function () {
+    }
+    moving() {
         this.cursor.setVisible(false);
-        var cursor = this.scene.world.cursorWorld;
+        const cursor = this.scene.world.cursorWorld;
         if (this.selectedTokens.length > 0) {
             if (!this.scene.i.mouseLeftDown()) {
                 this.movingTokens = false;
-                var identical = true;
-                var currSerialized = [];
-                for (var s = 0; s < this.selectedTokens.length; s++) {
+                let identical = true;
+                let currSerialized = [];
+                for (let s = 0; s < this.selectedTokens.length; s++) {
                     currSerialized.push(this.selectedTokens[s].serialize());
                     if (this.prevSerialized[s] != currSerialized[s])
                         identical = false;
@@ -2014,67 +1901,273 @@ var TokenMode = /** @class */ (function () {
                 }
                 return;
             }
-            var newTileGrabPos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
-            var offset_1 = new Vec2(newTileGrabPos.x - this.tileGrabPos.x, newTileGrabPos.y - this.tileGrabPos.y);
-            if (offset_1.x == 0 && offset_1.y == 0)
+            let newTileGrabPos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
+            let offset = new Vec2(newTileGrabPos.x - this.tileGrabPos.x, newTileGrabPos.y - this.tileGrabPos.y);
+            if (offset.x == 0 && offset.y == 0)
                 return;
             this.movedTokens = true;
             this.tileGrabPos = newTileGrabPos;
-            this.selectedTokens.forEach(function (tkn) { return tkn.setPosition(tkn.x / 4 + offset_1.x * 16, tkn.y / 4 + offset_1.y * 16); });
+            this.selectedTokens.forEach(tkn => tkn.setPosition(tkn.x / 4 + offset.x * 16, tkn.y / 4 + offset.y * 16));
         }
-    };
-    TokenMode.prototype.startMovingTokens = function () {
-        var _this = this;
+    }
+    startMovingTokens() {
         this.movedTokens = false;
         this.movingTokens = true;
-        var cursor = this.scene.world.cursorWorld;
+        const cursor = this.scene.world.cursorWorld;
         this.tileGrabPos = new Vec2(Math.floor(cursor.x / 64), Math.floor(cursor.y / 64));
         this.prevSerialized = [];
-        this.selectedTokens.forEach(function (t) { return _this.prevSerialized.push(t.serialize()); });
-    };
-    TokenMode.prototype.createToken = function () {
-        var token = new Token(this.scene, Math.floor(this.scene.world.cursorWorld.x / 4 / 16) * 16, Math.floor(this.scene.world.cursorWorld.y / 4 / 16) * 16, this.selectedTokenType);
+        this.selectedTokens.forEach(t => this.prevSerialized.push(t.serialize()));
+    }
+    createToken() {
+        let token = new Token(this.scene, Math.floor(this.scene.world.cursorWorld.x / 4 / 16) * 16, Math.floor(this.scene.world.cursorWorld.y / 4 / 16) * 16, this.selectedTokenType);
         this.scene.add.existing(token);
         this.scene.tokens.push(token);
         this.scene.history.push("token_create", { data: token.serialize() });
         return token;
-    };
-    TokenMode.prototype.removeToken = function (t) {
-        for (var i = 0; i < this.selectedTokens.length; i++)
+    }
+    removeToken(t) {
+        for (let i = 0; i < this.selectedTokens.length; i++)
             if (this.selectedTokens[i] == t)
                 this.selectedTokens.splice(i, 1);
-        for (var i = 0; i < this.scene.tokens.length; i++)
+        for (let i = 0; i < this.scene.tokens.length; i++)
             if (this.scene.tokens[i] == t)
                 this.scene.tokens.splice(i, 1);
         if (this.scene.token.hoveredToken == t)
             this.scene.token.hoveredToken = null;
         t.destroy();
-    };
-    TokenMode.prototype.cleanup = function () {
+    }
+    cleanup() {
         if (!this.active)
             return;
         this.active = false;
-        this.selectedTokens.forEach(function (t) { return t.setSelected(false); });
+        this.selectedTokens.forEach(t => t.setSelected(false));
         this.selectedTokens = [];
         if (this.hoveredToken != null)
             this.hoveredToken.setHovered(false);
         this.hoveredToken = null;
-        this.primitives.forEach(function (e) { return e.destroy(); });
+        this.primitives.forEach(e => e.destroy());
         this.primitives = [];
         this.cursor.setVisible(false);
         this.tokenPreview.setVisible(false);
         this.movingTokens = false;
-    };
-    return TokenMode;
-}());
+    }
+}
+class Lighting {
+    constructor(...any) {
+    }
+    update() {
+    }
+}
+class MapChunk {
+    constructor(map, x, y) {
+        this.dirtyList = [];
+        this.fullyDirty = false;
+        this.pos = new Vec2(x, y);
+        this.canvas = map.scene.add.renderTexture(x * MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE * 4, y * MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE * 4, MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE, MapChunk.CHUNK_SIZE * MapChunk.TILE_SIZE);
+        this.map = map;
+        this.canvas.setScale(4);
+        this.canvas.setOrigin(0, 0);
+        for (let i = 0; i < MapChunk.CHUNK_SIZE * MapChunk.CHUNK_SIZE; i++) {
+            let x = i % MapChunk.CHUNK_SIZE;
+            let y = Math.floor(i / MapChunk.CHUNK_SIZE);
+            let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+            let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+            if (mX >= this.map.size.x || mY >= this.map.size.y)
+                continue;
+            this.drawTile(x, y);
+        }
+    }
+    dirty(pos) {
+        if (!this.fullyDirty) {
+            for (let v of this.dirtyList)
+                if (v.equals(pos))
+                    return;
+            this.dirtyList.push(pos);
+            if (this.dirtyList.length > MapChunk.DIRTY_LIMIT) {
+                this.fullyDirty = true;
+                this.dirtyList = [];
+            }
+        }
+    }
+    rebuild() {
+        if (this.fullyDirty) {
+            for (let i = 0; i < MapChunk.CHUNK_SIZE * MapChunk.CHUNK_SIZE; i++) {
+                let x = i % MapChunk.CHUNK_SIZE;
+                let y = Math.floor(i / MapChunk.CHUNK_SIZE);
+                let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+                let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+                if (mX >= this.map.size.x || mY >= this.map.size.y)
+                    continue;
+                this.drawTile(x, y);
+            }
+            this.fullyDirty = false;
+            return true;
+        }
+        if (this.dirtyList.length == 0)
+            return false;
+        for (let elem of this.dirtyList)
+            this.drawTile(elem.x, elem.y);
+        this.dirtyList = [];
+        return true;
+    }
+    drawTile(x, y) {
+        let mX = x + this.pos.x * MapChunk.CHUNK_SIZE;
+        let mY = y + this.pos.y * MapChunk.CHUNK_SIZE;
+        let wallTile = this.map.getTile(1 /* wall */, mX, mY);
+        if (this.map.getTileset(1 /* wall */, mX, mY) == -1 || (wallTile < 54 || wallTile > 60)) {
+            this.canvas.drawFrame(this.map.manager.groundLocations[this.map.getTileset(0 /* floor */, mX, mY)].key, this.map.getTile(0 /* floor */, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+            if (this.map.getTileset(2 /* overlay */, mX, mY) != -1)
+                this.canvas.drawFrame(this.map.manager.overlayLocations[this.map.getTileset(2 /* overlay */, mX, mY)].key, this.map.getTile(2 /* overlay */, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+        }
+        if (this.map.getTileset(1 /* wall */, mX, mY) != -1)
+            this.canvas.drawFrame(this.map.manager.wallLocations[this.map.getTileset(1 /* wall */, mX, mY)].key, this.map.getTile(1 /* wall */, mX, mY), x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+        if ((x % 2 == 0 && y % 2 == 0) || (x % 2 != 0 && y % 2 != 0))
+            this.canvas.drawFrame('grid_tile', 0, x * MapChunk.TILE_SIZE, y * MapChunk.TILE_SIZE);
+    }
+}
+MapChunk.CHUNK_SIZE = 16;
+MapChunk.TILE_SIZE = 16;
+MapChunk.DIRTY_LIMIT = 32;
+class MapData {
+    constructor(scene, size) {
+        this.layers = {};
+        this.chunks = [];
+        this.scene = scene;
+        this.size = size;
+        this.manager = new TilesetManager(scene);
+        this.registerLayer(0 /* floor */, () => Math.floor(Math.random() * 6) + 54, 0);
+        this.registerLayer(1 /* wall */, 0, -1);
+        this.registerLayer(2 /* overlay */, 0, -1);
+        for (let i = 0; i < Math.ceil(size.y / MapChunk.CHUNK_SIZE); i++) {
+            this.chunks[i] = [];
+            for (let j = 0; j < Math.ceil(size.x / MapChunk.CHUNK_SIZE); j++) {
+                this.chunks[i][j] = new MapChunk(this, j, i);
+            }
+        }
+    }
+    update() {
+        let start = Date.now();
+        for (let arr of this.chunks)
+            for (let chunk of arr) {
+                chunk.rebuild();
+                if (Date.now() - start > 10)
+                    break;
+            }
+    }
+    setTile(layer, tileset, xx, yy) {
+        let x, y;
+        if (xx instanceof Vec2) {
+            x = xx.x;
+            y = xx.y;
+        }
+        else {
+            x = xx;
+            y = yy;
+        }
+        if (x < 0 || y < 0 || x >= this.size.x || y >= this.size.y)
+            return false;
+        let oldTileset = this.getTileset(layer, x, y);
+        if (oldTileset == tileset)
+            return false;
+        this.setTileset(layer, x, y, tileset);
+        this.smartTile(x, y);
+        return true;
+    }
+    setTileset(key, x, a, b) {
+        if (x instanceof Vec2)
+            this.layers[key].tilesets[x.y][x.x] = a;
+        else
+            this.layers[key].tilesets[a][x] = b;
+    }
+    getTile(key, xx, yy) {
+        let x, y;
+        if (xx instanceof Vec2) {
+            x = xx.x;
+            y = xx.y;
+        }
+        else {
+            x = xx;
+            y = yy;
+        }
+        return this.layers[key].tiles[clamp(y, 0, this.size.y - 1)][clamp(x, 0, this.size.x - 1)];
+    }
+    getTileset(key, xx, yy) {
+        let x, y;
+        if (xx instanceof Vec2) {
+            x = xx.x;
+            y = xx.y;
+        }
+        else {
+            x = xx;
+            y = yy;
+        }
+        return this.layers[key].tilesets[clamp(y, 0, this.size.y - 1)][clamp(x, 0, this.size.x - 1)];
+    }
+    smartTile(x, y) {
+        for (let i = clamp(x - 1, this.size.x - 1, 0); i <= clamp(x + 1, this.size.x - 1, 0); i++) {
+            for (let j = clamp(y - 1, this.size.y - 1, 0); j <= clamp(y + 1, this.size.y - 1, 0); j++) {
+                const solids = this.getTilesetsAt(1 /* wall */, i, j).map(i => i != -1);
+                const wall = SmartTiler.wall(solids, this.getTile(1 /* wall */, i, j));
+                if (wall != -1)
+                    this.setTileRaw(1 /* wall */, i, j, wall);
+                const floor = SmartTiler.floor(solids, this.getTile(0 /* floor */, i, j));
+                if (floor != -1)
+                    this.setTileRaw(0 /* floor */, i, j, floor);
+                const overlay = SmartTiler.overlay(this.getTilesetsAt(2 /* overlay */, i, j)
+                    .map(t => t == this.getTileset(2 /* overlay */, i, j)), this.getTileset(2 /* overlay */, i, j));
+                if (overlay != -1)
+                    this.setTileRaw(2 /* overlay */, i, j, overlay);
+            }
+        }
+    }
+    setTileRaw(key, x, a, b, c) {
+        if (x instanceof Vec2) {
+            this.layers[key].tiles[x.y][x.x] = a;
+            if (b !== undefined)
+                this.setTileset(key, x, b);
+            this.chunks[Math.floor(x.y / MapChunk.CHUNK_SIZE)][Math.floor(x.x / MapChunk.CHUNK_SIZE)]
+                .dirty(new Vec2(x.x % MapChunk.CHUNK_SIZE, x.y % MapChunk.CHUNK_SIZE));
+        }
+        else {
+            this.layers[key].tiles[a][x] = b;
+            if (c !== undefined)
+                this.setTileset(key, x, a, c);
+            this.chunks[Math.floor(a / MapChunk.CHUNK_SIZE)][Math.floor(x / MapChunk.CHUNK_SIZE)]
+                .dirty(new Vec2(x % MapChunk.CHUNK_SIZE, a % MapChunk.CHUNK_SIZE));
+        }
+    }
+    getTilesetsAt(layer, x, y) {
+        let tilesets = [];
+        for (let i = -1; i <= 1; i++)
+            for (let j = -1; j <= 1; j++)
+                tilesets.push(this.getTileset(layer, clamp(x + j, 0, this.size.x - 1), clamp(y + i, 0, this.size.y - 1)));
+        return tilesets;
+    }
+    registerLayer(key, startTile = 0, startTileset = -1) {
+        let layer = {
+            tiles: [],
+            tilesets: []
+        };
+        for (let i = 0; i < this.size.y; i++) {
+            layer.tiles[i] = [];
+            layer.tilesets[i] = [];
+            for (let j = 0; j < this.size.x; j++) {
+                let tile = typeof (startTile) == "number" ? startTile : startTile();
+                layer.tiles[i][j] = tile;
+                layer.tilesets[i][j] = startTileset;
+            }
+        }
+        this.layers[key] = layer;
+    }
+}
 var SmartTiler;
 (function (SmartTiler) {
     function wall(walls, current) {
-        var TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
+        const TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
         if (current == -1)
             return -1;
-        var empty = walls.map(function (b) { return !b; });
-        var tile = 54;
+        let empty = walls.map(b => !b);
+        let tile = 54;
         if (empty[T]) {
             if (empty[B]) {
                 if (empty[L]) {
@@ -2224,11 +2317,11 @@ var SmartTiler;
     }
     SmartTiler.wall = wall;
     function overlay(overlays, current) {
-        var TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
+        const TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
         if (current == -1)
             return -1;
-        var empty = overlays.map(function (b) { return !b; });
-        var tile = 54;
+        let empty = overlays.map(b => !b);
+        let tile = 54;
         if (empty[T]) {
             if (empty[B]) {
                 if (empty[L]) {
@@ -2377,11 +2470,11 @@ var SmartTiler;
         return tile;
     }
     SmartTiler.overlay = overlay;
-    function ground(walls, current) {
-        var TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
+    function floor(walls, current) {
+        const TL = 0, T = 1, TR = 2, L = 3, C = 4, R = 5, BL = 6, B = 7, BR = 8;
         if (current == -1)
             return -1;
-        var tile = 10;
+        let tile = 10;
         if (walls[C])
             tile = 10;
         else if (walls[B]) {
@@ -2525,315 +2618,173 @@ var SmartTiler;
         }
         return tile;
     }
-    SmartTiler.ground = ground;
+    SmartTiler.floor = floor;
 })(SmartTiler || (SmartTiler = {}));
-var Tilemap = /** @class */ (function () {
-    function Tilemap(key, scene, xwid, ywid) {
-        this.dimensions = new Vec2();
-        this.layers = {};
-        this.scene = scene;
-        this.dimensions = new Vec2(xwid, ywid);
-        this.groundAt = [];
-        this.wallAt = [];
-        this.overlayAt = [];
-        for (var i = 0; i < xwid; i++) {
-            this.groundAt[i] = [];
-            this.wallAt[i] = [];
-            this.overlayAt[i] = [];
-            for (var j = 0; j < ywid; j++) {
-                this.groundAt[i][j] = -1;
-                this.wallAt[i][j] = -1;
-                this.overlayAt[i][j] = -1;
-            }
-        }
-        this.manager = new TilesetManager(scene);
-        this.map = this.scene.add.tilemap(null, 16, 16, 0, 0);
-        for (var _i = 0, _a = this.manager.resolutions(); _i < _a.length; _i++) {
-            var res = _a[_i];
-            this.createLayers(parseInt(res));
-        }
-        for (var x = 0; x < this.dimensions.x; x++) {
-            for (var y = 0; y < this.dimensions.y; y++) {
-                this.setTileRaw(x, y, 1, 54 + Math.floor(Math.random() * 6), 0 /* GROUND */);
-            }
-        }
-        this.map.addTilesetImage("grid_tile", "grid_tile", 16, 16, 0, 0);
-        this.map.setLayer("grid");
-        var gridlayer = this.map.createBlankDynamicLayer("grid", "grid_tile", 0, 0, this.dimensions.x, this.dimensions.y, 16, 16);
-        gridlayer.setScale(4, 4);
-        gridlayer.setDepth(500);
-        for (var i = 0; i < xwid; i++) {
-            for (var j = 0; j < ywid; j++) {
-                if ((j % 2 == 0 && i % 2 == 0) || (j % 2 != 0 && i % 2 != 0))
-                    gridlayer.putTileAt(0, i, j);
-            }
-        }
-    }
-    Tilemap.prototype.createLayers = function (res) {
-        this.map.addTilesetImage("tileset_" + res + "_ground", "tileset_" + res + "_ground", res, res, 2, 4);
-        this.map.addTilesetImage("tileset_" + res + "_wall", "tileset_" + res + "_wall", res, res, 2, 4);
-        this.map.addTilesetImage("tileset_" + res + "_overlay", "tileset_" + res + "_overlay", res, res, 2, 4);
-        this.map.setLayer("layer_" + res + "_ground");
-        var ground = this.map.createBlankDynamicLayer("layer_" + res + "_ground", "tileset_" + res + "_ground", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-        ground.setScale(4 / (res / 16), 4 / (res / 16));
-        ground.setDepth(-1500 + res);
-        this.map.setLayer("layer_" + res + "_overlay");
-        var overlay = this.map.createBlankDynamicLayer("layer_" + res + "_overlay", "tileset_" + res + "_overlay", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-        overlay.setScale(4 / (res / 16), 4 / (res / 16));
-        overlay.setDepth(-1000 + res);
-        this.map.setLayer("layer_" + res + "_wall");
-        var wall = this.map.createBlankDynamicLayer("layer_" + res + "_wall", "tileset_" + res + "_wall", 0, 0, this.dimensions.x, this.dimensions.y, res, res);
-        wall.setScale(4 / (res / 16), 4 / (res / 16));
-        wall.setDepth(-500 + res);
-        this.layers[res] = [ground, wall, overlay];
-    };
-    Tilemap.prototype.getWall = function (x, y) {
-        return this.wallAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-    };
-    Tilemap.prototype.setWall = function (x, y, tileset) {
-        return this.setTile(x, y, tileset, 1 /* WALL */);
-    };
-    Tilemap.prototype.getGround = function (x, y) {
-        return this.groundAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-    };
-    Tilemap.prototype.setGround = function (x, y, tileset) {
-        return this.setTile(x, y, tileset, 0 /* GROUND */);
-    };
-    Tilemap.prototype.getOverlay = function (x, y) {
-        return this.overlayAt[clamp(x, 0, this.dimensions.x - 1)][clamp(y, 0, this.dimensions.y - 1)];
-    };
-    Tilemap.prototype.setOverlay = function (x, y, tileset) {
-        return this.setTile(x, y, tileset, 2 /* OVERLAY */);
-    };
-    Tilemap.prototype.getTile = function (x, y, layer) {
-        return (layer == 1 /* WALL */ ? this.getWall(x, y) : layer == 0 /* GROUND */ ? this.getGround(x, y) : this.getOverlay(x, y));
-    };
-    Tilemap.prototype.setTile = function (x, y, tileset, layer) {
-        if (x < 0 || y < 0 || x > this.dimensions.x - 1 || y > this.dimensions.y - 1)
-            return false;
-        var arr = (layer == 0 /* GROUND */ ? this.groundAt : layer == 1 /* WALL */ ? this.wallAt : this.overlayAt);
-        if (arr[x][y] == tileset)
-            return false;
-        if (arr[x][y] != -1) {
-            this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].removeTileAt(x, y, true);
-            arr[x][y] = -1;
-        }
-        if (tileset != -1)
-            this.layers[this.manager.getTilesetRes(tileset, layer)][layer].putTileAt(this.manager.getGlobalTileIndex(tileset, 0, layer), x, y);
-        arr[x][y] = tileset;
-        this.calculateSmartTilesAround(x, y);
-        return true;
-    };
-    Tilemap.prototype.setTileRaw = function (x, y, tileset, tile, layer) {
-        var arr = (layer == 0 /* GROUND */ ? this.groundAt : layer == 1 /* WALL */ ? this.wallAt : this.overlayAt);
-        if (arr[x][y] != -1) {
-            this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].removeTileAt(x, y, true);
-            arr[x][y] = -1;
-        }
-        var loc = this.manager.getTilesetRes(tileset, layer);
-        this.layers[loc][layer].putTileAt(this.manager.getGlobalTileIndex(tileset, tile, layer), x, y);
-        arr[x][y] = tileset;
-    };
-    Tilemap.prototype.getTileAt = function (x, y, layer) {
-        var arr = (layer == 0 /* GROUND */ ? this.groundAt : layer == 1 /* WALL */ ? this.wallAt : this.overlayAt);
-        if (arr[x][y] == -1)
-            return -1;
-        return this.manager.getLocalTileIndex(arr[x][y], this.layers[this.manager.getTilesetRes(arr[x][y], layer)][layer].getTileAt(x, y, true).index, layer);
-    };
-    Tilemap.prototype.calculateSmartTilesAround = function (x, y) {
-        for (var i = clamp(x - 1, this.dimensions.x - 1, 0); i <= clamp(x + 1, this.dimensions.x - 1, 0); i++) {
-            for (var j = clamp(y - 1, this.dimensions.y - 1, 0); j <= clamp(y + 1, this.dimensions.y - 1, 0); j++) {
-                var wall = SmartTiler.wall(this.getWallsAround(i, j), this.getTileAt(i, j, 1 /* WALL */));
-                if (wall != -1)
-                    this.setTileRaw(i, j, this.wallAt[i][j], wall, 1 /* WALL */);
-                var ground = SmartTiler.ground(this.getWallsAround(i, j), this.getTileAt(i, j, 0 /* GROUND */));
-                if (ground != -1)
-                    this.setTileRaw(i, j, this.groundAt[i][j], ground, 0 /* GROUND */);
-                var overlay = SmartTiler.overlay(this.getOverlaysAround(i, j, this.overlayAt[i][j]), this.getTileAt(i, j, 2 /* OVERLAY */));
-                if (overlay != -1)
-                    this.setTileRaw(i, j, this.overlayAt[i][j], overlay, 2 /* OVERLAY */);
-            }
-        }
-    };
-    Tilemap.prototype.getWallsAround = function (x, y) {
-        var solid = [];
-        for (var i = -1; i <= 1; i++) {
-            for (var j = -1; j <= 1; j++) {
-                solid.push(this.getWall(x + j, y + i) != -1);
-            }
-        }
-        return solid;
-    };
-    Tilemap.prototype.getOverlaysAround = function (x, y, targetTileset) {
-        var solid = [];
-        for (var i = -1; i <= 1; i++) {
-            for (var j = -1; j <= 1; j++) {
-                solid.push(this.getOverlay(x + j, y + i) == targetTileset);
-            }
-        }
-        return solid;
-    };
-    return Tilemap;
-}());
-var TilesetCanvas = /** @class */ (function () {
-    function TilesetCanvas(manager, res, layer) {
-        this.indexes = [];
-        this.indMap = [];
-        this.pad = 2;
-        this.manager = manager;
-        this.res = res;
-        this.width = Math.floor(1024 / ((this.res + this.pad * 2) * 9));
-        this.height = Math.floor(1024 / ((this.res + this.pad * 2) * 7));
-        this.canvas = manager.scene.textures.createCanvas("tileset_" + res +
-            (layer == 1 /* WALL */ ? "_wall" : layer == 0 /* GROUND */ ? "_ground" : "_overlay"), this.width * 9 * (this.res + this.pad * 2), this.height * 7 * (this.res + this.pad * 2));
-    }
-    TilesetCanvas.prototype.addTileset = function (key, ind) {
-        var x = this.indexes.length % this.width;
-        var y = Math.floor(this.indexes.length / this.width);
-        this.drawTileset(key, x, y);
-        this.indMap[ind] = this.indexes.length;
-        this.indexes.push(ind);
-    };
-    TilesetCanvas.prototype.getGlobalIndex = function (tileset, tile) {
-        var lX = tile % 9;
-        var lY = Math.floor(tile / 9);
-        var gX = tileset % this.width;
-        var gY = Math.floor(tileset / this.width);
-        var xx = lX + gX * 9;
-        var yy = lY + gY * 9;
-        return yy * this.width * 9 + xx;
-    };
-    TilesetCanvas.prototype.getLocalIndex = function (tile) {
-        var gX = tile % (this.width * 9);
-        var gY = Math.floor(tile / (this.width * 9));
-        var lX = gX % 9;
-        var lY = gY % 7;
-        return lX + lY * 9;
-    };
-    TilesetCanvas.prototype.drawTileset = function (key, x, y) {
-        var img = this.manager.scene.textures.get(key).getSourceImage();
-        var refCanvas = document.createElement('canvas');
-        refCanvas.width = img.width;
-        refCanvas.height = img.height;
-        refCanvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
-        var imageOffX = 9 * (this.res + this.pad * 2) * x;
-        var imageOffY = 7 * (this.res + this.pad * 2) * y;
-        for (var i = 0; i < 9; i++) {
-            for (var j = 0; j < 7; j++) {
-                var frame = i + j * 9;
-                var tileOffX = imageOffX + i * (this.res + this.pad * 2);
-                var tileOffY = imageOffY + j * (this.res + this.pad * 2);
-                for (var k = 0; k < this.res + this.pad * 2; k++) {
-                    for (var l = 0; l < this.pad * 2; l++) {
-                        var sX = clamp(k - this.pad, 0, this.res - 1);
-                        var sY = l < this.pad ? 0 : this.res - 1;
-                        var oY = l < this.pad ? l : l + this.res;
-                        var pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
-                        this.canvas.setPixel(tileOffX + k, tileOffY + oY, pixel[0], pixel[1], pixel[2], pixel[3]);
-                    }
-                }
-                for (var k = 0; k < this.pad * 2; k++) {
-                    for (var l = 0; l < this.res; l++) {
-                        var sX = k < this.pad ? 0 : this.res - 1;
-                        var sY = clamp(l, 0, this.res - 1);
-                        var oX = k < this.pad ? k : k + this.res;
-                        var pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
-                        this.canvas.setPixel(tileOffX + oX, tileOffY + l + this.pad, pixel[0], pixel[1], pixel[2], pixel[3]);
-                    }
-                }
-                this.canvas.drawFrame(key, frame, 9 * (this.res + this.pad * 2) * x + i * (this.res + this.pad * 2) + this.pad, 7 * (this.res + this.pad * 2) * y + j * (this.res + this.pad * 2) + this.pad);
-            }
-        }
-        refCanvas.remove();
-    };
-    return TilesetCanvas;
-}());
-var TilesetManager = /** @class */ (function () {
-    function TilesetManager(scene) {
+// class TilesetCanvas {
+// 	manager: TilesetManager;
+// 	res: number;
+// 	width: number;
+// 	height: number;
+// 	canvas: Phaser.Textures.CanvasTexture;
+// 	indexes: number[] = [];
+// 	indMap: number[] = [];
+// 	pad: number = 2;
+// 	constructor(manager: TilesetManager, res: number, layer: Layer) {
+// 		this.manager = manager;
+// 		this.res = res;
+// 		this.width = Math.floor(1024 / ((this.res + this.pad * 2) * 9));
+// 		this.height = Math.floor(1024 / ((this.res + this.pad * 2) * 7));
+// 		this.canvas = manager.scene.textures.createCanvas("tileset_" + res + 
+// 			(layer == Layer.wall ? "_wall" : layer == Layer.floor ? "_ground" : "_overlay"), 
+// 			this.width * 9 * (this.res + this.pad * 2), this.height * 7 * (this.res + this.pad * 2));
+// 	}
+// 	addTileset(key: string, ind: number) {
+// 		const x = this.indexes.length % this.width;
+// 		const y = Math.floor(this.indexes.length / this.width);
+// 		this.drawTileset(key, x, y);
+// 		this.indMap[ind] = this.indexes.length;
+// 		this.indexes.push(ind);
+// 	}
+// 	getGlobalIndex(tileset: number, tile: number) {
+// 		const lX = tile % 9;
+// 		const lY = Math.floor(tile / 9);
+// 		const gX = tileset % this.width;
+// 		const gY = Math.floor(tileset / this.width);
+// 		const xx = lX + gX * 9;
+// 		const yy = lY + gY * 9;
+// 		return yy * this.width * 9 + xx;
+// 	}
+// 	getLocalIndex(tile: number): number {
+// 		const gX = tile % (this.width * 9);
+// 		const gY = Math.floor(tile / (this.width * 9));
+// 		const lX = gX % 9;
+// 		const lY = gY % 7;
+// 		return lX + lY * 9;
+// 	}
+// 	private drawTileset(key: string, x: number, y: number) {
+// 	// 	let img: HTMLImageElement = this.manager.scene.textures.get(key).getSourceImage() as HTMLImageElement;
+// 	// 	let refCanvas = document.createElement('canvas');
+// 	// 	refCanvas.width = img.width;
+// 	// 	refCanvas.height = img.height;
+// 	// 	refCanvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
+// 	// 	let imageOffX = 9 * (this.res + this.pad * 2) * x;
+// 	// 	let imageOffY = 7 * (this.res + this.pad * 2) * y;
+// 	// 	for (let i = 0; i < 9; i++) {
+// 	// 		for (let j = 0; j < 7; j++) {
+// 	// 			let frame = i + j * 9;
+// 	// 			let tileOffX = imageOffX + i * (this.res + this.pad * 2);
+// 	// 			let tileOffY = imageOffY + j * (this.res + this.pad * 2);
+// 	// 			for (let k = 0; k < this.res + this.pad * 2; k++) {
+// 	// 				for (let l = 0; l < this.pad * 2; l++) {
+// 	// 					let sX = clamp(k - this.pad, 0, this.res - 1);
+// 	// 					let sY = l < this.pad ? 0 : this.res - 1;
+// 	// 					let oY = l < this.pad ? l : l + this.res;
+// 	// 					let pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
+// 	// 					this.canvas.setPixel(tileOffX + k, tileOffY + oY, pixel[0], pixel[1], pixel[2], pixel[3]);
+// 	// 				}
+// 	// 			}
+// 	// 			for (let k = 0; k < this.pad * 2; k++) {
+// 	// 				for (let l = 0; l < this.res; l++) {
+// 	// 					let sX = k < this.pad ? 0 : this.res - 1;
+// 	// 					let sY = clamp(l, 0, this.res - 1);
+// 	// 					let oX = k < this.pad ? k : k + this.res;
+// 	// 					let pixel = refCanvas.getContext('2d').getImageData(this.res * i + sX, this.res * j + sY, 1, 1).data;
+// 	// 					this.canvas.setPixel(tileOffX + oX, tileOffY + l + this.pad, pixel[0], pixel[1], pixel[2], pixel[3]);
+// 	// 				}
+// 	// 			}
+// 	// 			this.canvas.drawFrame(key, frame, 
+// 	// 				9 * (this.res + this.pad * 2) * x + i * (this.res + this.pad * 2) + this.pad, 
+// 	// 				7 * (this.res + this.pad * 2) * y + j * (this.res + this.pad * 2) + this.pad)
+// 	// 		}
+// 	// 	}
+// 	// 	refCanvas.remove();
+// 	}
+// }
+class TilesetManager {
+    constructor(scene) {
         this.currentWallInd = 0;
         this.currentGroundInd = 0;
         this.currentOverlayInd = 0;
         this.wallLocations = {};
         this.groundLocations = {};
         this.overlayLocations = {};
-        this.canvases = {};
         this.indexes = {};
         this.scene = scene;
-        for (var _i = 0, WALLS_3 = WALLS; _i < WALLS_3.length; _i++) {
-            var tileset = WALLS_3[_i];
-            this.addTileset(tileset.key, 1 /* WALL */);
-        }
-        for (var _a = 0, GROUNDS_3 = GROUNDS; _a < GROUNDS_3.length; _a++) {
-            var tileset = GROUNDS_3[_a];
-            this.addTileset(tileset.key, 0 /* GROUND */);
-        }
-        for (var _b = 0, OVERLAYS_3 = OVERLAYS; _b < OVERLAYS_3.length; _b++) {
-            var tileset = OVERLAYS_3[_b];
-            this.addTileset(tileset.key, 2 /* OVERLAY */);
-        }
+        for (let tileset of WALLS)
+            this.addTileset(tileset.key, 1 /* wall */);
+        for (let tileset of GROUNDS)
+            this.addTileset(tileset.key, 0 /* floor */);
+        for (let tileset of OVERLAYS)
+            this.addTileset(tileset.key, 2 /* overlay */);
     }
-    TilesetManager.prototype.addTileset = function (key, layer) {
-        var res = this.scene.textures.get(key).getSourceImage(0).width / 9;
-        if (this.canvases[res] == undefined)
-            this.canvases[res] = [new TilesetCanvas(this, res, 0 /* GROUND */), new TilesetCanvas(this, res, 1 /* WALL */), new TilesetCanvas(this, res, 2 /* OVERLAY */)];
-        var ind = (layer == 1 /* WALL */ ? this.currentWallInd : layer == 0 /* GROUND */ ? this.currentGroundInd : this.currentOverlayInd);
-        var canvas = this.canvases[res];
-        this[layer == 1 /* WALL */ ? "wallLocations" : layer == 0 /* GROUND */ ? "groundLocations" : "overlayLocations"][ind] = { res: res, ind: ind, key: key };
+    addTileset(key, layer) {
+        let res = this.scene.textures.get(key).getSourceImage(0).width / 9;
+        let ind = (layer == 1 /* wall */ ? this.currentWallInd : layer == 0 /* floor */ ? this.currentGroundInd : this.currentOverlayInd);
+        this[layer == 1 /* wall */ ? "wallLocations" : layer == 0 /* floor */ ? "groundLocations" : "overlayLocations"][ind] = { res: res, ind: ind, key: key };
         this.indexes[key] = ind;
-        canvas[layer].addTileset(key, ind);
-        layer == 1 /* WALL */ ? this.currentWallInd++ :
-            layer == 0 /* GROUND */ ? this.currentGroundInd++ :
+        layer == 1 /* wall */ ? this.currentWallInd++ :
+            layer == 0 /* floor */ ? this.currentGroundInd++ :
                 this.currentOverlayInd++;
-    };
-    TilesetManager.prototype.resolutions = function () {
-        var resList = [];
-        for (var _i = 0, _a = Object.keys(this.canvases); _i < _a.length; _i++) {
-            var res = _a[_i];
-            resList.push(res);
-        }
-        return resList;
-    };
-    TilesetManager.prototype.getTilesetRes = function (tileset, layer) {
-        return layer == 1 /* WALL */ ? this.wallLocations[tileset].res
-            : layer == 0 /* GROUND */ ? this.groundLocations[tileset].res
-                : this.overlayLocations[tileset].res;
-    };
-    TilesetManager.prototype.getGlobalTileIndex = function (tileset, tile, layer) {
-        return this.canvases[this.getTilesetRes(tileset, layer)][layer].getGlobalIndex(tileset, tile);
-    };
-    TilesetManager.prototype.getLocalTileIndex = function (tileset, tile, layer) {
-        return this.canvases[this.getTilesetRes(tileset, layer)][layer].getLocalIndex(tile);
-    };
-    return TilesetManager;
-}());
-var BrightenPipeline = /** @class */ (function (_super) {
-    __extends(BrightenPipeline, _super);
-    function BrightenPipeline(game) {
-        var _this = this;
-        var config = { game: game,
-            renderer: game.renderer,
-            fragShader: "\n\t\t\tprecision mediump float;\n\n\t\t\tuniform sampler2D uMainSampler;\n\n\t\t\tvarying vec2 outTexCoord;\n\t\t\t\n\t\t\tvoid main(void) {\n\t\t\t\tvec4 color  = texture2D(uMainSampler, outTexCoord);\n\t\t\t\tif (color.a == 0.0) discard;\n\t\t\t\tcolor += vec4(0.2, 0.2, 0.2, 0);\n\t\t\t\tgl_FragColor = color;\n\t\t\t}"
-        };
-        _this = _super.call(this, config) || this;
-        return _this;
     }
-    return BrightenPipeline;
-}(Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline));
-var OutlinePipeline = /** @class */ (function (_super) {
-    __extends(OutlinePipeline, _super);
-    function OutlinePipeline(game) {
-        var _this = this;
-        var config = { game: game,
+}
+class BrightenPipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
+    constructor(game) {
+        let config = { game: game,
             renderer: game.renderer,
-            fragShader: "\n\t\t\tprecision mediump float;\n\n\t\t\tuniform sampler2D uMainSampler;\n\t\t\tuniform float tex_size;\n\n\t\t\tvarying vec2 outTexCoord;\n\t\t\t\n\t\t\tvoid main(void) {\n\t\t\t\tfloat factor = 1.0 / tex_size;\n\n\t\t\t\tvec4 color  = texture2D(uMainSampler, outTexCoord);\n\t\t\t\tvec4 colorU = texture2D(uMainSampler, vec2(outTexCoord.x, outTexCoord.y + factor));\n\t\t\t\tvec4 colorD = texture2D(uMainSampler, vec2(outTexCoord.x, outTexCoord.y - factor));\n\t\t\t\tvec4 colorL = texture2D(uMainSampler, vec2(outTexCoord.x + factor, outTexCoord.y));\n\t\t\t\tvec4 colorR = texture2D(uMainSampler, vec2(outTexCoord.x - factor, outTexCoord.y));\n\t\t\t\t\n\t\t\t\tif (color.a == 0.0 && (colorU.a != 0.0 || colorD.a != 0.0 || colorL.a != 0.0 || colorR.a != 0.0)) {\n\t\t\t\t\tgl_FragColor = vec4(1.0, 1.0, 1.0, 1);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (color.a == 0.0) discard;\n\t\t\t\t\tcolor += vec4(0.1, 0.1, 0.1, 0);\n\t\t\t\t\tgl_FragColor = color;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}"
+            fragShader: `
+			precision mediump float;
+
+			uniform sampler2D uMainSampler;
+
+			varying vec2 outTexCoord;
+			
+			void main(void) {
+				vec4 color  = texture2D(uMainSampler, outTexCoord);
+				if (color.a == 0.0) discard;
+				color += vec4(0.2, 0.2, 0.2, 0);
+				gl_FragColor = color;
+			}`
         };
-        _this = _super.call(this, config) || this;
-        return _this;
+        super(config);
     }
-    return OutlinePipeline;
-}(Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline));
-var InputManager = /** @class */ (function () {
-    function InputManager(scene) {
+}
+class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
+    constructor(game) {
+        let config = { game: game,
+            renderer: game.renderer,
+            fragShader: `
+			precision mediump float;
+
+			uniform sampler2D uMainSampler;
+			uniform float tex_size;
+
+			varying vec2 outTexCoord;
+			
+			void main(void) {
+				float factor = 1.0 / tex_size;
+
+				vec4 color  = texture2D(uMainSampler, outTexCoord);
+				vec4 colorU = texture2D(uMainSampler, vec2(outTexCoord.x, outTexCoord.y + factor));
+				vec4 colorD = texture2D(uMainSampler, vec2(outTexCoord.x, outTexCoord.y - factor));
+				vec4 colorL = texture2D(uMainSampler, vec2(outTexCoord.x + factor, outTexCoord.y));
+				vec4 colorR = texture2D(uMainSampler, vec2(outTexCoord.x - factor, outTexCoord.y));
+				
+				if (color.a == 0.0 && (colorU.a != 0.0 || colorD.a != 0.0 || colorL.a != 0.0 || colorR.a != 0.0)) {
+					gl_FragColor = vec4(1.0, 1.0, 1.0, 1);
+				}
+				else {
+					if (color.a == 0.0) discard;
+					color += vec4(0.1, 0.1, 0.1, 0);
+					gl_FragColor = color;
+				}
+				
+			}`
+        };
+        super(config);
+    }
+}
+class InputManager {
+    constructor(scene) {
         this.leftMouseState = false;
         this.rightMouseState = false;
         this.middleMouseState = false;
@@ -2852,71 +2803,70 @@ var InputManager = /** @class */ (function () {
         this.keys.LEFT = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT);
         this.keys.RIGHT = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT);
         this.keys.DELETE = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DELETE);
-        for (var i = 0; i < 26; i++) {
-            var letter = (i + 10).toString(36).toUpperCase();
+        for (let i = 0; i < 26; i++) {
+            let letter = (i + 10).toString(36).toUpperCase();
             this.keys[letter] = scene.input.keyboard.addKey(letter);
         }
-        for (var i = 0; i <= 9; i++) {
+        for (let i = 0; i <= 9; i++) {
             this.keys[i + ""] = scene.input.keyboard.addKey(i + "");
         }
-        for (var key in this.keys) {
+        for (let key in this.keys) {
             this.keysDown[key] = false;
             this.keysDownLast[key] = false;
         }
     }
-    InputManager.prototype.update = function () {
+    update() {
         this.leftMouseStateLast = this.leftMouseState;
         this.leftMouseState = this.scene.input.activePointer.leftButtonDown();
         this.rightMouseStateLast = this.rightMouseState;
         this.rightMouseState = this.scene.input.activePointer.rightButtonDown();
         this.middleMouseStateLast = this.middleMouseState;
         this.rightMouseState = this.scene.input.activePointer.middleButtonDown();
-        for (var key in this.keys)
+        for (let key in this.keys)
             this.keysDownLast[key] = this.keysDown[key];
-        for (var key in this.keys)
+        for (let key in this.keys)
             this.keysDown[key] = this.keys[key].isDown;
-    };
-    InputManager.prototype.mouseDown = function () {
+    }
+    mouseDown() {
         return this.leftMouseState || this.rightMouseState;
-    };
-    InputManager.prototype.mousePressed = function () {
+    }
+    mousePressed() {
         return (this.leftMouseState && !this.leftMouseStateLast) || (this.rightMouseState && !this.rightMouseStateLast);
-    };
-    InputManager.prototype.mouseReleased = function () {
+    }
+    mouseReleased() {
         return (!this.leftMouseState && this.leftMouseStateLast) || (!this.rightMouseState && this.rightMouseStateLast);
-    };
-    InputManager.prototype.mouseLeftDown = function () {
+    }
+    mouseLeftDown() {
         return this.leftMouseState;
-    };
-    InputManager.prototype.mouseLeftPressed = function () {
+    }
+    mouseLeftPressed() {
         return this.leftMouseState && !this.leftMouseStateLast;
-    };
-    InputManager.prototype.mouseLeftReleased = function () {
+    }
+    mouseLeftReleased() {
         return !this.leftMouseState && this.leftMouseStateLast;
-    };
-    InputManager.prototype.mouseRightDown = function () {
+    }
+    mouseRightDown() {
         return this.rightMouseState;
-    };
-    InputManager.prototype.mouseRightPressed = function () {
+    }
+    mouseRightPressed() {
         return this.rightMouseState && !this.rightMouseStateLast;
-    };
-    InputManager.prototype.mouseRightReleased = function () {
+    }
+    mouseRightReleased() {
         return !this.rightMouseState && this.rightMouseStateLast;
-    };
-    InputManager.prototype.keyDown = function (key) {
+    }
+    keyDown(key) {
         return this.keysDown[key.toUpperCase()];
-    };
-    InputManager.prototype.keyPressed = function (key) {
+    }
+    keyPressed(key) {
         return this.keysDown[key.toUpperCase()] && !this.keysDownLast[key.toUpperCase()];
-    };
-    InputManager.prototype.keyReleased = function (key) {
+    }
+    keyReleased(key) {
         return !this.keysDown[key.toUpperCase()] && this.keysDownLast[key.toUpperCase()];
-    };
-    return InputManager;
-}());
+    }
+}
 function clamp(x, min, max) {
     if (min > max) {
-        var t = max;
+        let t = max;
         max = min;
         min = t;
     }
@@ -2926,15 +2876,15 @@ function dec2hex(dec) {
     return ('0' + dec.toString(16)).substr(-2);
 }
 function generateId(len) {
-    var arr = new Uint8Array((len || 40) / 2);
+    let arr = new Uint8Array((len || 40) / 2);
     window.crypto.getRandomValues(arr);
-    var stringArr = [];
-    for (var i = 0; i < arr.length; i++)
+    let stringArr = [];
+    for (let i = 0; i < arr.length; i++)
         stringArr.push(dec2hex(arr[i]));
     return stringArr.join('');
 }
-var Vec2 = /** @class */ (function () {
-    function Vec2(x, y) {
+class Vec2 {
+    constructor(x, y) {
         this.x = 0;
         this.y = 0;
         if (x == null)
@@ -2951,10 +2901,12 @@ var Vec2 = /** @class */ (function () {
             this.y = x.y;
         }
     }
-    return Vec2;
-}());
-var Vec3 = /** @class */ (function () {
-    function Vec3(x, y, z) {
+    equals(o) {
+        return this.x == o.x && this.y == o.y;
+    }
+}
+class Vec3 {
+    constructor(x, y, z) {
         this.x = 0;
         this.y = 0;
         this.z = 0;
@@ -2977,10 +2929,12 @@ var Vec3 = /** @class */ (function () {
             this.z = x.z;
         }
     }
-    return Vec3;
-}());
-var Vec4 = /** @class */ (function () {
-    function Vec4(x, y, z, w) {
+    equals(o) {
+        return this.x == o.x && this.y == o.y && this.z == o.z;
+    }
+}
+class Vec4 {
+    constructor(x, y, z, w) {
         this.x = 0;
         this.y = 0;
         this.z = 0;
@@ -3007,5 +2961,7 @@ var Vec4 = /** @class */ (function () {
             this.w = x.w;
         }
     }
-    return Vec4;
-}());
+    equals(o) {
+        return this.x == o.x && this.y == o.y && this.z == o.z && this.w == o.w;
+    }
+}
diff --git a/tsconfig.json b/tsconfig.json
index cefb186..5422e24 100755
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,7 @@
 {
+	"lib": "es6",
 	"compilerOptions": {
-		"target": "es5",
+		"target": "es6",
 		"rootDirs": [
 			"src/",
 			"src/*"