diff --git a/src/application/base/baseEvent.ts b/src/application/base/baseEvent.ts
index e24ade1..84d6bc9 100644
--- a/src/application/base/baseEvent.ts
+++ b/src/application/base/baseEvent.ts
@@ -28,6 +28,7 @@ export abstract class BaseEvent {
   }
 
   protected async getCharacter(): Promise<Character | null> {
+    if (!this.socket.characterId) return null
     const characterRepository = new CharacterRepository()
     return characterRepository.getById(this.socket.characterId)
   }
diff --git a/src/events/disconnect.ts b/src/events/disconnect.ts
index 2d109cd..f570ce3 100644
--- a/src/events/disconnect.ts
+++ b/src/events/disconnect.ts
@@ -4,7 +4,7 @@ import MapManager from '@/managers/mapManager'
 
 export default class DisconnectEvent extends BaseEvent {
   public listen(): void {
-    this.socket.on(SocketEvent.DISCONNECT, this.handleEvent.bind(this))
+    this.socket.on('disconnect', this.handleEvent.bind(this))
   }
 
   private async handleEvent(): Promise<void> {
@@ -16,7 +16,7 @@ export default class DisconnectEvent extends BaseEvent {
 
       this.io.emit(SocketEvent.USER_DISCONNECT, this.socket.userId)
 
-      const mapCharacter = MapManager.getCharacterById(this.socket.characterId)
+      const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
       if (!mapCharacter) {
         this.logger.info('User disconnected but had no character set')
         return
diff --git a/src/events/map/characterMove.ts b/src/events/map/characterMove.ts
index ec1649d..203c411 100644
--- a/src/events/map/characterMove.ts
+++ b/src/events/map/characterMove.ts
@@ -9,54 +9,59 @@ import TeleportService from '@/services/characterTeleportService'
 
 export default class CharacterMove extends BaseEvent {
   private readonly characterService = CharacterService
-  private readonly MOVEMENT_THROTTLE = 230 // Minimum time between movement requests
+  private readonly STEP_DELAY = 150 // Milliseconds between each tile movement
+  private readonly THROTTLE_DELAY = 230 // Minimum time between movement requests
+  private movementTimeout: NodeJS.Timeout | null = null
 
   public listen(): void {
     this.socket.on(SocketEvent.MAP_CHARACTER_MOVE, this.handleEvent.bind(this))
   }
 
   private async handleEvent({ positionX, positionY }: { positionX: number; positionY: number }): Promise<void> {
-    const mapCharacter = MapManager.getCharacterById(this.socket.characterId)
-    if (!mapCharacter?.getCharacter()) {
-      this.logger.error('map:character:move error: Character not found or not initialized')
-      return
-    }
-
-    if (this.isThrottled(`movement_${this.socket.characterId}`, this.MOVEMENT_THROTTLE)) {
-      // Only cancel current movement if the new target is different
-      if (mapCharacter.isMoving && (Math.floor(positionX) !== Math.floor(mapCharacter.character.positionX) || Math.floor(positionY) !== Math.floor(mapCharacter.character.positionY))) {
-        mapCharacter.isMoving = false
-        mapCharacter.currentPath = null
-        // this.finalizeMovement(mapCharacter)
+    try {
+      const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
+      if (!mapCharacter?.getCharacter()) {
+        this.logger.error('map:character:move error: Character not found or not initialized')
+        return
       }
-      return
-    }
 
-    // If already moving, cancel current movement
-    if (mapCharacter.isMoving && mapCharacter.currentPath && mapCharacter.currentPath.length > 2) {
+      // Cancel any ongoing movement
+      this.cancelCurrentMovement(mapCharacter)
+
+      // Throttle rapid movement requests
+      if (this.isThrottled(`movement_${this.socket.characterId}`, this.THROTTLE_DELAY)) {
+        return
+      }
+
+      // Calculate path to target position
+      const path = await this.characterService.calculatePath(mapCharacter.character, Math.floor(positionX), Math.floor(positionY))
+
+      if (!path?.length) {
+        this.io.in(mapCharacter.character.map.id).emit(SocketEvent.MAP_CHARACTER_MOVEERROR, 'No valid path found')
+        return
+      }
+
+      // Start new movement
+      mapCharacter.isMoving = true
+      mapCharacter.currentPath = path
+      await this.moveAlongPath(mapCharacter)
+    } catch (error: any) {
+      this.logger.error('map:character:move error: ' + error.message)
+    }
+  }
+
+  private cancelCurrentMovement(mapCharacter: MapCharacter): void {
+    if (mapCharacter.isMoving) {
       mapCharacter.isMoving = false
       mapCharacter.currentPath = null
     }
-
-    // Validate target position is within reasonable range
-    const currentX = mapCharacter.character.positionX
-    const currentY = mapCharacter.character.positionY
-    const distance = Math.sqrt(Math.pow(positionX - currentX, 2) + Math.pow(positionY - currentY, 2))
-
-    const path = await this.characterService.calculatePath(mapCharacter.character, positionX, positionY)
-    if (!path?.length) {
-      this.io.in(mapCharacter.character.map.id).emit(SocketEvent.MAP_CHARACTER_MOVEERROR, 'No valid path found')
-      return
-    }
-
-    // Start new movement
-    mapCharacter.isMoving = true
-    mapCharacter.currentPath = path
-    await this.moveAlongPath(mapCharacter, path)
   }
 
-  private async moveAlongPath(mapCharacter: MapCharacter, path: Array<{ positionX: number; positionY: number }>): Promise<void> {
+  private async moveAlongPath(mapCharacter: MapCharacter): Promise<void> {
     const character = mapCharacter.getCharacter()
+    const path = mapCharacter.currentPath
+
+    if (!path?.length) return
 
     try {
       for (let i = 0; i < path.length - 1; i++) {
@@ -64,47 +69,42 @@ export default class CharacterMove extends BaseEvent {
           return
         }
 
-        const [start, end] = [path[i], path[i + 1]]
+        const [currentTile, nextTile] = [path[i], path[i + 1]]
 
-        if (!start || !end) {
-          this.logger.error('Invalid path step detected')
+        if (!currentTile || !nextTile) {
+          this.logger.error('Invalid movement step detected')
           break
         }
 
-        if (i !== 0) {
-          await this.characterService.applyMovementDelay()
-        }
-
-        // Validate each step
-        if (Math.abs(end.positionX - start.positionX) > 1 || Math.abs(end.positionY - start.positionY) > 1) {
-          this.logger.error('Invalid path step detected')
+        // Validate step
+        if (!this.isValidStep(currentTile, nextTile)) {
+          this.logger.error('Invalid movement step detected')
           break
         }
 
-        character.setRotation(CharacterService.calculateRotation(start.positionX, start.positionY, end.positionX, end.positionY))
+        // Update character rotation
+        character.setRotation(CharacterService.calculateRotation(currentTile.positionX, currentTile.positionY, nextTile.positionX, nextTile.positionY))
 
-        const mapEventTileRepository = new MapEventTileRepository()
-        const mapEventTile = await mapEventTileRepository.getEventTileByMapIdAndPosition(character.getMap().getId(), Math.floor(end.positionX), Math.floor(end.positionY))
-
-        if (mapEventTile?.type === 'BLOCK') break
-        if (mapEventTile?.type === 'TELEPORT' && mapEventTile.teleport) {
-          await this.handleTeleportMapEventTile(mapEventTile as MapEventTileWithTeleport)
-          return
+        // Check for map events at the next tile
+        const mapEventTile = await this.checkMapEvents(character, nextTile)
+        if (mapEventTile) {
+          if (mapEventTile.type === 'BLOCK') break
+          if (mapEventTile.type === 'TELEPORT' && mapEventTile.teleport) {
+            await this.handleTeleportMapEventTile(mapEventTile as MapEventTileWithTeleport)
+            return
+          }
         }
 
-        // Update position first
-        character.setPositionX(end.positionX).setPositionY(end.positionY)
+        // Move character to next tile
+        character.setPositionX(nextTile.positionX).setPositionY(nextTile.positionY)
 
-        // Then emit with the same properties
-        this.io.in(character.map.id).emit(SocketEvent.MAP_CHARACTER_MOVE, {
-          characterId: character.id,
-          positionX: character.getPositionX(),
-          positionY: character.getPositionY(),
-          rotation: character.getRotation(),
-          isMoving: true
-        })
+        // Broadcast movement
+        this.broadcastMovement(character, true)
 
-        await this.characterService.applyMovementDelay()
+        // Apply movement delay between steps
+        await new Promise((resolve) => setTimeout(resolve, this.STEP_DELAY))
+        if (i < path.length - 2) {
+        }
       }
     } finally {
       if (mapCharacter.isMoving && mapCharacter.currentPath === path) {
@@ -113,25 +113,52 @@ export default class CharacterMove extends BaseEvent {
     }
   }
 
+  private isValidStep(current: { positionX: number; positionY: number }, next: { positionX: number; positionY: number }): boolean {
+    return Math.abs(next.positionX - current.positionX) <= 1 && Math.abs(next.positionY - current.positionY) <= 1
+  }
+
+  private async checkMapEvents(character: any, nextTile: { positionX: number; positionY: number }) {
+    const mapEventTileRepository = new MapEventTileRepository()
+    return mapEventTileRepository.getEventTileByMapIdAndPosition(character.getMap().getId(), Math.floor(nextTile.positionX), Math.floor(nextTile.positionY))
+  }
+
   private async handleTeleportMapEventTile(mapEventTile: MapEventTileWithTeleport): Promise<void> {
-    if (mapEventTile.getTeleport()) {
-      await TeleportService.teleportCharacter(this.socket.characterId, {
-        targetMapId: mapEventTile.getTeleport()!.getToMap().getId(),
-        targetX: mapEventTile.getTeleport()!.getToPositionX(),
-        targetY: mapEventTile.getTeleport()!.getToPositionY(),
-        rotation: mapEventTile.getTeleport()!.getToRotation()
+    const teleport = mapEventTile.getTeleport()
+    if (teleport) {
+      await TeleportService.teleportCharacter(this.socket.characterId!, {
+        targetMapId: teleport.getToMap().getId(),
+        targetX: teleport.getToPositionX(),
+        targetY: teleport.getToPositionY(),
+        rotation: teleport.getToRotation()
       })
     }
   }
 
-  private finalizeMovement(mapCharacter: MapCharacter): void {
-    mapCharacter.isMoving = false
-    this.io.in(mapCharacter.character.map.id).emit(SocketEvent.MAP_CHARACTER_MOVE, {
-      characterId: mapCharacter.character.id,
-      positionX: mapCharacter.character.positionX,
-      positionY: mapCharacter.character.positionY,
-      rotation: mapCharacter.character.rotation,
-      isMoving: mapCharacter.isMoving
+  private broadcastMovement(character: any, isMoving: boolean): void {
+    this.io.in(character.map.id).emit(SocketEvent.MAP_CHARACTER_MOVE, {
+      characterId: character.id,
+      positionX: character.getPositionX(),
+      positionY: character.getPositionY(),
+      rotation: character.getRotation(),
+      isMoving
     })
   }
+
+  private finalizeMovement(mapCharacter: MapCharacter): void {
+    // Clear any existing timeout
+    if (this.movementTimeout) {
+      clearTimeout(this.movementTimeout)
+    }
+
+    // Set new timeout
+    this.movementTimeout = setTimeout(() => {
+      // Only finalize if there are no pending movements
+      if (mapCharacter.currentPath === null) {
+        mapCharacter.isMoving = false
+        this.broadcastMovement(mapCharacter.character, false)
+      }
+    }, this.STEP_DELAY)
+
+    mapCharacter.currentPath = null
+  }
 }