diff --git a/package-lock.json b/package-lock.json
index 7850df2..3581de6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1765,9 +1765,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.14.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz",
-      "integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==",
+      "version": "20.14.1",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.1.tgz",
+      "integrity": "sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -3401,9 +3401,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.788",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz",
-      "integrity": "sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA==",
+      "version": "1.4.789",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.789.tgz",
+      "integrity": "sha512-0VbyiaXoT++Fi2vHGo2ThOeS6X3vgRCWrjPeO2FeIAWL6ItiSJ9BqlH8LfCXe3X1IdcG+S0iLoNaxQWhfZoGzQ==",
       "dev": true,
       "license": "ISC"
     },
@@ -4544,9 +4544,9 @@
       "license": "ISC"
     },
     "node_modules/jackspeak": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
-      "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.2.3.tgz",
+      "integrity": "sha512-htOzIMPbpLid/Gq9/zaz9SfExABxqRe1sSCdxntlO/aMD6u0issZQiY25n2GKQUtJ02j7z5sfptlAOMpWWOmvw==",
       "dev": true,
       "license": "BlueOak-1.0.0",
       "dependencies": {
diff --git a/src/components/Game.vue b/src/components/Game.vue
index c780e89..2ef00a1 100644
--- a/src/components/Game.vue
+++ b/src/components/Game.vue
@@ -1,8 +1,6 @@
 <template>
   <div class="game-container">
-    <div class="top-ui">
-      <Hud />
-    </div>
+    <div class="top-ui"><Hud /></div>
 
     <Game :config="gameConfig" class="game" @create="bootGame">
       <Scene name="main" @preload="preloadScene" @create="bootScene">
@@ -57,7 +55,7 @@ const preloadScene = (scene: Phaser.Scene) => {
   scene.load.image('tiles', '/assets/tiles/default.png')
   scene.load.image('waypoint', '/assets/waypoint.png')
   scene.textures.addBase64(
-    'player',
+    'character',
     'data:image/png;base64,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'
   )
 }
diff --git a/src/components/World.vue b/src/components/World.vue
index ce65386..fa832a9 100644
--- a/src/components/World.vue
+++ b/src/components/World.vue
@@ -1,19 +1,19 @@
 <template>
-  <TilemapLayer v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
+  <TilemapLayerC v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
   <Controls :layer="layer" />
-  <Character :layer="layer" />
-  <Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length > 0">
+  <Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length">
     <Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />
   </Container>
 </template>
 
 <script setup lang="ts">
-import { Container, refObj, TilemapLayer, useScene } from 'phavuer'
-import Character from '@/components/sprites/Character.vue'
-import {Character as CharacterType} from '@/types'
 import config from '@/config'
-import { onBeforeMount, onMounted, reactive, ref, type Ref, toRaw, watch } from 'vue'
 import Tileset = Phaser.Tilemaps.Tileset
+import TilemapLayer = Phaser.Tilemaps.TilemapLayer
+import { Container, TilemapLayer as TilemapLayerC, useScene } from 'phavuer'
+import Character from '@/components/sprites/Character.vue'
+import {type Character as CharacterType} from '@/types'
+import { onBeforeMount, ref, type Ref, watch } from 'vue'
 import Controls from '@/components/Controls.vue'
 import { useSocketStore } from '@/stores/socket'
 import { useZoneStore } from '@/stores/zone'
@@ -30,8 +30,8 @@ let zoneData = new Phaser.Tilemaps.MapData({
   format: Phaser.Tilemaps.Formats.ARRAY_2D
 })
 let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData)
-let tileset: any = tileMap.addTilesetImage('default', 'tiles')
-let layer: typeof TilemapLayer | null = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y)
+let tileset: Tileset = tileMap.addTilesetImage('default', 'tiles') as Tileset
+let layer: TilemapLayer = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y) as TilemapLayer
 
 // center camera
 const centerY = (tileMap.height * tileMap.tileHeight) / 2
@@ -43,44 +43,37 @@ const zoneStore = useZoneStore()
 const socket = useSocketStore()
 
 // Watch for changes in the zoneStore and update the layer
-watch(
-  () => zoneStore.tiles,
-  () => {
+watch(() => zoneStore.tiles, () => {
     // @TODO : change to tiles for when loading other maps
     zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)))
-  },
-  { deep: true }
+  }, { deep: true }
 )
 
 // Load the zone from the server
 onBeforeMount(() => {
-  socket.getConnection.emit('character:zone:load')
+  socket.getConnection.emit('character:zone:load', {zoneId: socket.character.zoneId})
 })
 
 // Listen for the zone event from the server and load the zone
 socket.getConnection.on('character:zone:load', (data) => {
   console.log('character:zone:load', data)
   zoneStore.loadTiles(data.zone.tiles)
-  /**
-   * @TODO
-   * bug , when 2nd player joins, the first player is not added to the zone
-   */
 
-  // console.log(data.players);
-  // console.log(data.players[1]); // key is user id
-  //
-  // // remove self from the players list
-  // delete data.players[socket.getConnection.id];
-  //
-  // zoneStore.addPlayers(data.players);
+  let characters = data.characters;
+  zoneStore.setCharacters(characters);
 })
 
 // Listen for player join events
-socket.getConnection.on('character:zone:character_join', (data: CharacterType) => {
-  console.log('character:zone:character_join', data)
+socket.getConnection.on('zone:character:join', (data: CharacterType) => {
+  console.log('character:zone:join', data)
   zoneStore.addCharacter(data)
 })
 
+// Listen for user:disconnect
+socket.getConnection.on('user:disconnect', (data: CharacterType) => {
+  zoneStore.removeCharacter(data)
+})
+
 /**
  * 1 tile is 64x32
  * the zone is 10x10
diff --git a/src/components/sprites/Character.vue b/src/components/sprites/Character.vue
index f518f2e..c049f6f 100644
--- a/src/components/sprites/Character.vue
+++ b/src/components/sprites/Character.vue
@@ -1,8 +1,9 @@
 <template>
   <Container>
+    <!-- @TODO : Text position X must be calculated based on the character name length -->
     <Text
-      :text="props.character?.name ?? socket.character.name"
-      :x="position.x - 50"
+      :text="props.character?.name"
+      :x="position.x - 40"
       :y="position.y - 80"
       :style="{
         fontFamily: 'Helvetica, Arial',
@@ -13,91 +14,76 @@
         stroke: '#213547'
       }"
     />
-    <Sprite ref="sprite" texture="player" :x="position.x" :y="position.y" />
+    <Sprite ref="sprite" texture="character" :x="position.x" :y="position.y" />
   </Container>
 </template>
 
 <script lang="ts" setup>
 import { Container, onPostUpdate, onPreUpdate, Sprite, Text, useScene } from 'phavuer'
-import { reactive, type Ref, ref } from 'vue'
+import { onMounted, reactive, type Ref, ref } from 'vue'
 import config from '@/config'
 import { useSocketStore } from '@/stores/socket'
-import {type Character as CharacterT } from '@/types'
+import { type Character as CharacterT } from '@/types'
 
 const socket = useSocketStore()
 
 const props = defineProps({
   layer: Phaser.Tilemaps.TilemapLayer,
-  character: {
-    type: Object as () => CharacterT | undefined,
-    default: undefined
-  }
+  character: Object as () => CharacterT
 })
 
 const scene = useScene()
+const position = reactive({ x: props.character.position_x, y: props.character.position_y })
+const isSelf = props.character.id === socket.character.id;
 
-// onPreUpdate((time, delta) => {
-//   console.log(time, delta);
-// })
+onMounted(() => {
+  if (isSelf) setupSelf()
 
-const position = reactive({ x: 0, y: 0 })
-
-if (props.character !== undefined) {
-  console.log('character', props.character)
-  position.x = props.character?.position_x
-  position.y = props.character?.position_y
-}
-
-const pointer_tile = ref(undefined)
-
-function onPointerClick(pointer: Phaser.Input.Pointer) {
-  const px = scene.cameras.main.worldView.x + pointer.x
-  const py = scene.cameras.main.worldView.y + pointer.y
-
-  pointer_tile.value = getTile(px, py, props.layer)
-  if (pointer_tile.value) {
-    const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
-    position.x = worldPoint.x + config.tile_size.y
-    position.y = worldPoint.y
-
-    socket.getConnection.emit('move', { x: position.x, y: position.y })
+  if (!isSelf) {
   }
+});
 
-  //Directions for player sprites + animations
-  if (px < 0 && py > 0) {
-    console.log('down left')
-  } else if (px < 0 && py < 0) {
-    console.log('top left')
-  } else if (px > 0 && py > 0) {
-    console.log('down right')
-  } else if (px > 0 && py < 0) {
-    console.log('top right')
-  }
-}
-
-if (!props.character) {
+function setupSelf()
+{
   scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
-}
+  const pointer_tile = ref(undefined)
+  function onPointerClick(pointer: Phaser.Input.Pointer) {
+    if (!isSelf) return;
 
-socket.getConnection.on('character:move', (data: any) => {
-  console.log('character moved', data)
+    const px = scene.cameras.main.worldView.x + pointer.x
+    const py = scene.cameras.main.worldView.y + pointer.y
 
-  if (data.id !== props.character?.id) {
-    console.log('not you')
-    return
+    pointer_tile.value = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
+    if (pointer_tile.value) {
+      const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
+      const position_x = worldPoint.x + config.tile_size.y
+      const position_y = worldPoint.y
+      socket.getConnection.emit('character:move', { position_x, position_y })
+    }
+
+    //Directions for player sprites + animations
+    if (px < 0 && py > 0) {
+      console.log('down left')
+    } else if (px < 0 && py < 0) {
+      console.log('top left')
+    } else if (px > 0 && py > 0) {
+      console.log('down right')
+    } else if (px > 0 && py < 0) {
+      console.log('top right')
+    }
   }
 
+  function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
+    const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
+    if (!tile) return undefined;
+    return tile
+  }
+}
+
+socket.getConnection.on('character:moved', (data: CharacterT) => {
+  console.log('character:moved', data);
+  if (data.id !== props.character.id) return; // Only update the character that moved
   position.x = data.position_x
   position.y = data.position_y
 })
-
-function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
-  const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
-
-  if (!tile) {
-    return undefined
-  }
-
-  return tile
-}
 </script>
diff --git a/src/engine/Map/IMap.ts b/src/engine/Map/IMap.ts
deleted file mode 100644
index 240d5cd..0000000
--- a/src/engine/Map/IMap.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { Character } from '@/types'
-
-export default interface IMap {
-  readonly id: number
-  name: string
-  width: number
-  height: number
-  data: any
-  characters: Array<Character> | []
-}
diff --git a/src/engine/Map/Map.ts b/src/engine/Map/Map.ts
deleted file mode 100644
index 32ceb15..0000000
--- a/src/engine/Map/Map.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import type IMap from '@/engine/Map/IMap'
-import Player from '@/engine/Player/Player'
-import type { Character } from '@/types'
-
-export default class Map implements IMap {
-  id: number
-  name: string
-  width: number
-  height: number
-  data: any
-  characters: Character[]
-
-  constructor(id: number, name: string, width: number, height: number, data: any, characters: Character[]) {
-    this.id = id
-    this.name = name
-    this.width = width
-    this.height = height
-    this.data = data
-    this.characters = characters
-  }
-
-  public addCharacter(character: Character) {
-    this.characters.push(character)
-  }
-
-  public removeCharacter(character: Character) {
-    this.characters = this.characters.filter((c: Character) => c.id !== character.id)
-  }
-
-  public moveCharacter(character: Character, x: number, y: number) {
-    const index = this.characters.findIndex((c: Character) => c.id === character.id)
-    this.characters[index].position_x = x
-    this.characters[index].position_y = y
-  }
-}
diff --git a/src/engine/Player/IPlayer.ts b/src/engine/Player/IPlayer.ts
deleted file mode 100644
index 433f41b..0000000
--- a/src/engine/Player/IPlayer.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export default interface IPlayer {
-  readonly id: number
-  name: string
-  coords: {
-    x: number
-    y: number
-  }
-}
diff --git a/src/engine/Player/Player.ts b/src/engine/Player/Player.ts
deleted file mode 100644
index 8e99a2c..0000000
--- a/src/engine/Player/Player.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import type IPlayer from '@/engine/Player/IPlayer'
-
-export default class Player implements IPlayer {
-  id: number
-  name: string
-  coords: { x: number; y: number }
-
-  constructor(id: number, name: string, coords: { x: number; y: number }) {
-    this.id = id
-    this.name = name
-    this.coords = coords
-  }
-}
diff --git a/src/stores/socket.ts b/src/stores/socket.ts
index 77e038f..fde5f35 100644
--- a/src/stores/socket.ts
+++ b/src/stores/socket.ts
@@ -3,7 +3,6 @@ import { io, Socket } from 'socket.io-client'
 import { useCookies } from '@vueuse/integrations/useCookies'
 import config from '@/config'
 import type { Character, User } from '@/types'
-import { useNotificationStore } from '@/stores/notifications'
 
 export const useSocketStore: StoreDefinition = defineStore('socket', {
   state: () => ({