diff --git a/src/components/gameMaster/zoneEditor/EventTiles.vue b/src/components/gameMaster/zoneEditor/EventTiles.vue
index 76ecc63..00ffdb8 100644
--- a/src/components/gameMaster/zoneEditor/EventTiles.vue
+++ b/src/components/gameMaster/zoneEditor/EventTiles.vue
@@ -8,7 +8,7 @@ import { useZoneEditorStore } from '@/stores/zoneEditorStore'
 import { Image, useScene } from 'phavuer'
 import { getTile, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
 import { uuidv4 } from '@/utilities'
-import { onBeforeMount, onBeforeUnmount } from 'vue'
+import { onMounted, onUnmounted } from 'vue'
 
 const scene = useScene()
 const zoneEditorStore = useZoneEditorStore()
@@ -102,14 +102,14 @@ function eraser(pointer: Phaser.Input.Pointer) {
   zoneEditorStore.zone.zoneEventTiles = zoneEditorStore.zone.zoneEventTiles.filter((eventTile) => eventTile.id !== existingEventTile.id)
 }
 
-onBeforeMount(() => {
+onMounted(() => {
   scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
   scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
   scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
   scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
 })
 
-onBeforeUnmount(() => {
+onUnmounted(() => {
   scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
   scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
   scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
diff --git a/src/components/gameMaster/zoneEditor/Objects.vue b/src/components/gameMaster/zoneEditor/Objects.vue
index 8eacc87..ce0d3aa 100644
--- a/src/components/gameMaster/zoneEditor/Objects.vue
+++ b/src/components/gameMaster/zoneEditor/Objects.vue
@@ -10,7 +10,7 @@ import { Image, useScene } from 'phavuer'
 import { useZoneEditorStore } from '@/stores/zoneEditorStore'
 import type { ZoneObject } from '@/types'
 import SelectedZoneObject from '@/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue'
-import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
+import { onMounted, onUnmounted, ref, watch } from 'vue'
 
 const scene = useScene()
 const zoneEditorStore = useZoneEditorStore()
@@ -155,14 +155,14 @@ function deleteZoneObject(id: string) {
   selectedZoneObject.value = null
 }
 
-onBeforeMount(() => {
+onMounted(() => {
   scene.input.on(Phaser.Input.Events.POINTER_DOWN, pencil)
   scene.input.on(Phaser.Input.Events.POINTER_MOVE, pencil)
   scene.input.on(Phaser.Input.Events.POINTER_DOWN, eraser)
   scene.input.on(Phaser.Input.Events.POINTER_MOVE, eraser)
 })
 
-onBeforeUnmount(() => {
+onUnmounted(() => {
   scene.input.off(Phaser.Input.Events.POINTER_DOWN, pencil)
   scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
   scene.input.off(Phaser.Input.Events.POINTER_DOWN, eraser)
diff --git a/src/components/gameMaster/zoneEditor/Tiles.vue b/src/components/gameMaster/zoneEditor/Tiles.vue
index cfd6c67..b4ad75a 100644
--- a/src/components/gameMaster/zoneEditor/Tiles.vue
+++ b/src/components/gameMaster/zoneEditor/Tiles.vue
@@ -7,7 +7,7 @@ import config from '@/config'
 import { useScene } from 'phavuer'
 import { useGameStore } from '@/stores/gameStore'
 import { useZoneEditorStore } from '@/stores/zoneEditorStore'
-import { onBeforeMount, onBeforeUnmount } from 'vue'
+import { onMounted, onUnmounted } from 'vue'
 import { createTileArray, getTile, placeTile, setLayerTiles } from '@/composables/zoneComposable'
 import Controls from '@/components/utilities/Controls.vue'
 
@@ -123,7 +123,7 @@ function paint(pointer: Phaser.Input.Pointer) {
   zoneEditorStore.zone.tiles = createTileArray(zoneTilemap.width, zoneTilemap.height, zoneEditorStore.selectedTile.id)
 }
 
-onBeforeMount(() => {
+onMounted(() => {
   if (!zoneEditorStore.zone?.tiles) {
     return
   }
@@ -134,7 +134,7 @@ onBeforeMount(() => {
   scene.input.on(Phaser.Input.Events.POINTER_DOWN, paint)
 })
 
-onBeforeUnmount(() => {
+onUnmounted(() => {
   scene.input.off(Phaser.Input.Events.POINTER_MOVE, pencil)
   scene.input.off(Phaser.Input.Events.POINTER_MOVE, eraser)
   scene.input.off(Phaser.Input.Events.POINTER_DOWN, paint)
diff --git a/src/components/utilities/Notifications.vue b/src/components/utilities/Notifications.vue
index c964e11..f188299 100644
--- a/src/components/utilities/Notifications.vue
+++ b/src/components/utilities/Notifications.vue
@@ -12,7 +12,7 @@
 <script setup lang="ts">
 import { useGameStore } from '@/stores/gameStore'
 import Modal from '@/components/utilities/Modal.vue'
-import { onBeforeMount, onBeforeUnmount, watch } from 'vue'
+import { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, watch } from 'vue'
 
 const gameStore = useGameStore()
 
@@ -34,7 +34,7 @@ function setupNotificationListener(connection: any) {
   })
 }
 
-onBeforeMount(() => {
+onMounted(() => {
   const connection = gameStore.connection
   if (connection) {
     setupNotificationListener(connection)
@@ -49,7 +49,7 @@ onBeforeMount(() => {
   }
 })
 
-onBeforeUnmount(() => {
+onUnmounted(() => {
   const connection = gameStore.connection
   if (connection) {
     connection.off('notification')
diff --git a/src/components/zone/Zone.vue b/src/components/zone/Zone.vue
index 5cf3a46..093eab3 100644
--- a/src/components/zone/Zone.vue
+++ b/src/components/zone/Zone.vue
@@ -7,7 +7,7 @@
 <script setup lang="ts">
 import { useGameStore } from '@/stores/gameStore'
 import { useZoneStore } from '@/stores/zoneStore'
-import { onBeforeUnmount, ref, onBeforeMount } from 'vue'
+import { ref, onUnmounted, onMounted } from 'vue'
 import type { Character as CharacterT, Zone as ZoneT, ExtendedCharacter as ExtendedCharacterT } from '@/types'
 import ZoneTiles from '@/components/zone/ZoneTiles.vue'
 import ZoneObjects from '@/components/zone/ZoneObjects.vue'
@@ -51,15 +51,15 @@ gameStore.connection!.on('character:move', (data: ExtendedCharacterT) => {
   zoneStore.updateCharacter(data)
 })
 
-onBeforeMount(async () => {
+onMounted(async () => {
+  // Emit zone:character:join event to server and wait for response, then set zone and characters
   gameStore!.connection!.emit('zone:character:join', async (response: zoneLoadData) => {
-    // Set zone and characters
     zoneStore.setZone(response.zone)
     zoneStore.setCharacters(response.characters)
   })
 })
 
-onBeforeUnmount(() => {
+onUnmounted(() => {
   zoneStore.reset()
   gameStore.connection!.off('zone:character:teleport')
   gameStore.connection!.off('zone:character:join')
diff --git a/src/components/zone/ZoneTiles.vue b/src/components/zone/ZoneTiles.vue
index 116d105..008a64e 100644
--- a/src/components/zone/ZoneTiles.vue
+++ b/src/components/zone/ZoneTiles.vue
@@ -6,17 +6,34 @@
 import config from '@/config'
 import { useScene } from 'phavuer'
 import { useZoneStore } from '@/stores/zoneStore'
-import { onBeforeMount, onBeforeUnmount } from 'vue'
-import { setLayerTiles } from '@/composables/zoneComposable'
+import { onBeforeUnmount } from 'vue'
+import { setLayerTiles, loadZoneTileTexture } from '@/composables/zoneComposable'
 import Controls from '@/components/utilities/Controls.vue'
 
 const emit = defineEmits(['tilemap:create'])
 
 const zoneStore = useZoneStore()
 const scene = useScene()
+
+const tilesFromZone = zoneStore.zone?.tiles
+const uniqueTiles = new Set(tilesFromZone.flat().filter(Boolean))
+
+/**
+ * @TODO fix this
+ */
+for (const tile of uniqueTiles) {
+  console.log(tile)
+  await loadZoneTileTexture(scene, tile, new Date())
+}
+
 const zoneTilemap = createTilemap()
 const tiles = createTileLayer()
 
+/**
+ * A Tilemap is a container for Tilemap data.
+ * This isn't a display object, rather, it holds data about the map and allows you to add tilesets and tilemap layers to it.
+ * A map can have one or more tilemap layers, which are the display objects that actually render the tiles.
+ */
 function createTilemap() {
   const zoneData = new Phaser.Tilemaps.MapData({
     width: zoneStore.zone?.width,
@@ -31,6 +48,9 @@ function createTilemap() {
   return tilemap
 }
 
+/**
+ * A Tileset is a combination of a single image containing the tiles and a container for data about each tile.
+ */
 function createTileLayer() {
   const tilesFromZone = zoneStore.zone?.tiles || []
   const uniqueTiles = new Set(tilesFromZone.flat().filter(Boolean))
@@ -49,12 +69,7 @@ function createTileLayer() {
   return layer
 }
 
-onBeforeMount(() => {
-  if (!zoneStore.zone?.tiles) {
-    return
-  }
-  setLayerTiles(zoneTilemap, tiles, zoneStore.zone.tiles)
-})
+setLayerTiles(zoneTilemap, tiles, zoneStore.zone?.tiles)
 
 onBeforeUnmount(() => {
   zoneTilemap.destroyLayer('tiles')
diff --git a/src/components/zone/partials/ZoneObject.vue b/src/components/zone/partials/ZoneObject.vue
index fbf9df0..dba2a80 100644
--- a/src/components/zone/partials/ZoneObject.vue
+++ b/src/components/zone/partials/ZoneObject.vue
@@ -3,14 +3,9 @@
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, computed } from 'vue'
+import { ref, computed } from 'vue'
 import { Image, useScene } from 'phavuer'
-import {
-  calculateIsometricDepth,
-  loadZoneObjectTexture,
-  tileToWorldX,
-  tileToWorldY
-} from '@/composables/zoneComposable'
+import { calculateIsometricDepth, loadZoneObjectTexture, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable'
 import type { ZoneObject } from '@/types'
 
 const props = defineProps<{
@@ -31,13 +26,11 @@ const imageProps = computed(() => ({
   originX: Number(props.zoneObject.object.originY)
 }))
 
-onMounted(() => {
-  loadZoneObjectTexture(scene, props.zoneObject.object.id, props.zoneObject.object.updatedAt)
-    .then((loaded) => {
-      isTextureLoaded.value = loaded
-    })
-    .catch((error) => {
-      console.error('Error loading texture:', error)
-    })
-})
+loadZoneObjectTexture(scene, props.zoneObject.object.id, props.zoneObject.object.updatedAt)
+  .then((loaded) => {
+    isTextureLoaded.value = loaded
+  })
+  .catch((error) => {
+    console.error('Error loading texture:', error)
+  })
 </script>
diff --git a/src/composables/zoneComposable.ts b/src/composables/zoneComposable.ts
index 6204483..b8161a4 100644
--- a/src/composables/zoneComposable.ts
+++ b/src/composables/zoneComposable.ts
@@ -52,6 +52,8 @@ export function placeTile(zone: Tilemap, layer: TilemapLayer, x: number, y: numb
 }
 
 export function setLayerTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
+  if (!tiles) return
+
   tiles.forEach((row: string[], y: number) => {
     row.forEach((tile: string, x: number) => {
       placeTile(zone, layer, x, y, tile)
@@ -71,6 +73,33 @@ export const calculateIsometricDepth = (x: number, y: number, width: number = 0,
   return baseDepth + (width + height) / (2 * config.tile_size.x)
 }
 
+export async function loadZoneTileTexture(scene: Phaser.Scene, textureId: string, updatedAt: Date): Promise<boolean> {
+  const assetManager = useAssetManager
+
+  // Check if the texture is already loaded in Phaser
+  if (scene.textures.exists(textureId)) {
+    return true
+  }
+
+  let assetData = await assetManager.getAsset(textureId)
+
+  if (!assetData) {
+    await assetManager.downloadAsset(textureId, `/assets/tiles/${textureId}.png`, 'tiles', updatedAt)
+    assetData = await assetManager.getAsset(textureId)
+  }
+
+  if (assetData) {
+    return new Promise<boolean>((resolve) => {
+      scene.textures.addBase64(textureId, assetData.data)
+      scene.textures.once(`addtexture-${textureId}`, () => {
+        resolve(true)
+      })
+    })
+  }
+
+  return false
+}
+
 export async function loadZoneObjectTexture(scene: Phaser.Scene, textureId: string, updatedAt: Date): Promise<boolean> {
   const assetManager = useAssetManager
 
diff --git a/src/screens/Game.vue b/src/screens/Game.vue
index a77d9a2..c9cf98d 100644
--- a/src/screens/Game.vue
+++ b/src/screens/Game.vue
@@ -83,24 +83,24 @@ function preloadScene(scene: Phaser.Scene) {
    *  We're using rex-await-loader to load assets asynchronously
    *  Phaser does not support this out of the box, so we're using this plugin
    */
-  scene.load.rexAwait(async function (successCallback) {
-    await assetManager.getAssetsByGroup('tiles').then((assets) => {
-      assets.forEach((asset) => {
-        if (scene.load.textureManager.exists(asset.key)) return
-        scene.textures.addBase64(asset.key, asset.data)
-      })
-    })
-
-    // Load objects
-    await assetManager.getAssetsByGroup('objects').then((assets) => {
-      assets.forEach((asset) => {
-        if (scene.load.textureManager.exists(asset.key)) return
-        scene.textures.addBase64(asset.key, asset.data)
-      })
-    })
-
-    successCallback()
-  })
+  // scene.load.rexAwait(async function (successCallback) {
+  //   await assetManager.getAssetsByGroup('tiles').then((assets) => {
+  //     assets.forEach((asset) => {
+  //       if (scene.load.textureManager.exists(asset.key)) return
+  //       scene.textures.addBase64(asset.key, asset.data)
+  //     })
+  //   })
+  //
+  //   // Load objects
+  //   await assetManager.getAssetsByGroup('objects').then((assets) => {
+  //     assets.forEach((asset) => {
+  //       if (scene.load.textureManager.exists(asset.key)) return
+  //       scene.textures.addBase64(asset.key, asset.data)
+  //     })
+  //   })
+  //
+  //   successCallback()
+  // })
 }
 
 function createScene(scene: Phaser.Scene) {
@@ -108,15 +108,15 @@ function createScene(scene: Phaser.Scene) {
    * Create sprite animations
    * This is done here because phaser forces us to
    */
-  assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
-    assets.forEach((asset) => {
-      scene.anims.create({
-        key: asset.key,
-        frameRate: 7,
-        frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
-        repeat: -1
-      })
-    })
-  })
+  // assetManager.getAssetsByGroup('sprite_animations').then((assets) => {
+  //   assets.forEach((asset) => {
+  //     scene.anims.create({
+  //       key: asset.key,
+  //       frameRate: 7,
+  //       frames: scene.anims.generateFrameNumbers(asset.key, { start: 0, end: asset.frameCount! - 1 }),
+  //       repeat: -1
+  //     })
+  //   })
+  // })
 }
 </script>