diff --git a/migrations/Migration20250101224501.ts b/migrations/Migration20250102162954.ts
similarity index 65%
rename from migrations/Migration20250101224501.ts
rename to migrations/Migration20250102162954.ts
index 2e55324..99e3bf0 100644
--- a/migrations/Migration20250101224501.ts
+++ b/migrations/Migration20250102162954.ts
@@ -1,10 +1,26 @@
 import { Migration } from '@mikro-orm/migrations';
 
-export class Migration20250101224501 extends Migration {
+export class Migration20250102162954 extends Migration {
 
   override async up(): Promise<void> {
+    this.addSql(`create table \`map\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`width\` int not null default 10, \`height\` int not null default 10, \`tiles\` json null, \`pvp\` tinyint(1) not null default false, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+
+    this.addSql(`create table \`map_effect\` (\`id\` varchar(255) not null, \`map_id\` varchar(255) not null, \`effect\` varchar(255) not null, \`strength\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`alter table \`map_effect\` add index \`map_effect_map_id_index\`(\`map_id\`);`);
+
+    this.addSql(`create table \`map_event_tile\` (\`id\` varchar(255) not null, \`map_id\` varchar(255) not null, \`type\` enum('BLOCK', 'TELEPORT', 'NPC', 'ITEM') not null, \`position_x\` int not null, \`position_y\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`alter table \`map_event_tile\` add index \`map_event_tile_map_id_index\`(\`map_id\`);`);
+
+    this.addSql(`create table \`map_event_tile_teleport\` (\`id\` varchar(255) not null, \`map_event_tile_id\` varchar(255) not null, \`to_map_id\` varchar(255) not null, \`to_rotation\` int not null, \`to_position_x\` int not null, \`to_position_y\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`alter table \`map_event_tile_teleport\` add unique \`map_event_tile_teleport_map_event_tile_id_unique\`(\`map_event_tile_id\`);`);
+    this.addSql(`alter table \`map_event_tile_teleport\` add index \`map_event_tile_teleport_to_map_id_index\`(\`to_map_id\`);`);
+
     this.addSql(`create table \`map_object\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`tags\` json null, \`origin_x\` int not null default 0, \`origin_y\` int not null default 0, \`is_animated\` tinyint(1) not null default false, \`frame_rate\` int not null default 0, \`frame_width\` int not null default 0, \`frame_height\` int not null default 0, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
 
+    this.addSql(`create table \`placed_map_object\` (\`id\` varchar(255) not null, \`map_id\` varchar(255) not null, \`map_object_id\` varchar(255) not null, \`depth\` int not null default 0, \`is_rotated\` tinyint(1) not null default false, \`position_x\` int not null default 0, \`position_y\` int not null default 0, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`alter table \`placed_map_object\` add index \`placed_map_object_map_id_index\`(\`map_id\`);`);
+    this.addSql(`alter table \`placed_map_object\` add index \`placed_map_object_map_object_id_index\`(\`map_object_id\`);`);
+
     this.addSql(`create table \`sprite\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
 
     this.addSql(`create table \`item\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`description\` varchar(255) null, \`item_type\` enum('WEAPON', 'HELMET', 'CHEST', 'LEGS', 'BOOTS', 'GLOVES', 'RING', 'NECKLACE') not null, \`stackable\` tinyint(1) not null default false, \`rarity\` enum('COMMON', 'UNCOMMON', 'RARE', 'EPIC', 'LEGENDARY') not null default 'COMMON', \`sprite_id\` varchar(255) null, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
@@ -29,20 +45,16 @@ export class Migration20250101224501 extends Migration {
     this.addSql(`alter table \`password_reset_token\` add index \`password_reset_token_user_id_index\`(\`user_id\`);`);
     this.addSql(`alter table \`password_reset_token\` add unique \`password_reset_token_token_unique\`(\`token\`);`);
 
-    this.addSql(`create table \`world\` (\`date\` datetime not null, \`is_rain_enabled\` tinyint(1) not null default false, \`rain_percentage\` int not null default 0, \`is_fog_enabled\` tinyint(1) not null default false, \`fog_density\` int not null default 0, primary key (\`date\`)) default character set utf8mb4 engine = InnoDB;`);
-
-    this.addSql(`create table \`zone\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`width\` int not null default 10, \`height\` int not null default 10, \`tiles\` json null, \`pvp\` tinyint(1) not null default false, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
-
-    this.addSql(`create table \`character\` (\`id\` varchar(255) not null, \`user_id\` varchar(255) not null, \`name\` varchar(255) not null, \`online\` tinyint(1) not null default false, \`role\` varchar(255) not null default 'player', \`zone_id\` varchar(255) not null, \`position_x\` int not null default 0, \`position_y\` int not null default 0, \`rotation\` int not null default 0, \`character_type_id\` varchar(255) null, \`character_hair_id\` varchar(255) null, \`alignment\` int not null default 50, \`hitpoints\` int not null default 100, \`mana\` int not null default 100, \`level\` int not null default 1, \`experience\` int not null default 0, \`strength\` int not null default 10, \`dexterity\` int not null default 10, \`intelligence\` int not null default 10, \`wisdom\` int not null default 10, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`create table \`character\` (\`id\` varchar(255) not null, \`user_id\` varchar(255) not null, \`name\` varchar(255) not null, \`online\` tinyint(1) not null default false, \`role\` varchar(255) not null default 'player', \`map_id\` varchar(255) not null, \`position_x\` int not null default 0, \`position_y\` int not null default 0, \`rotation\` int not null default 0, \`character_type_id\` varchar(255) null, \`character_hair_id\` varchar(255) null, \`alignment\` int not null default 50, \`hitpoints\` int not null default 100, \`mana\` int not null default 100, \`level\` int not null default 1, \`experience\` int not null default 0, \`strength\` int not null default 10, \`dexterity\` int not null default 10, \`intelligence\` int not null default 10, \`wisdom\` int not null default 10, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
     this.addSql(`alter table \`character\` add index \`character_user_id_index\`(\`user_id\`);`);
     this.addSql(`alter table \`character\` add unique \`character_name_unique\`(\`name\`);`);
-    this.addSql(`alter table \`character\` add index \`character_zone_id_index\`(\`zone_id\`);`);
+    this.addSql(`alter table \`character\` add index \`character_map_id_index\`(\`map_id\`);`);
     this.addSql(`alter table \`character\` add index \`character_character_type_id_index\`(\`character_type_id\`);`);
     this.addSql(`alter table \`character\` add index \`character_character_hair_id_index\`(\`character_hair_id\`);`);
 
-    this.addSql(`create table \`chat\` (\`id\` varchar(255) not null, \`character_id\` varchar(255) not null, \`zone_id\` varchar(255) not null, \`message\` varchar(255) not null, \`created_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
+    this.addSql(`create table \`chat\` (\`id\` varchar(255) not null, \`character_id\` varchar(255) not null, \`map_id\` varchar(255) not null, \`message\` varchar(255) not null, \`created_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
     this.addSql(`alter table \`chat\` add index \`chat_character_id_index\`(\`character_id\`);`);
-    this.addSql(`alter table \`chat\` add index \`chat_zone_id_index\`(\`zone_id\`);`);
+    this.addSql(`alter table \`chat\` add index \`chat_map_id_index\`(\`map_id\`);`);
 
     this.addSql(`create table \`character_item\` (\`id\` varchar(255) not null, \`character_id\` varchar(255) not null, \`item_id\` varchar(255) not null, \`quantity\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
     this.addSql(`alter table \`character_item\` add index \`character_item_character_id_index\`(\`character_id\`);`);
@@ -52,19 +64,17 @@ export class Migration20250101224501 extends Migration {
     this.addSql(`alter table \`character_equipment\` add index \`character_equipment_character_id_index\`(\`character_id\`);`);
     this.addSql(`alter table \`character_equipment\` add index \`character_equipment_character_item_id_index\`(\`character_item_id\`);`);
 
-    this.addSql(`create table \`zone_effect\` (\`id\` varchar(255) not null, \`zone_id\` varchar(255) not null, \`effect\` varchar(255) not null, \`strength\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
-    this.addSql(`alter table \`zone_effect\` add index \`zone_effect_zone_id_index\`(\`zone_id\`);`);
+    this.addSql(`create table \`world\` (\`date\` datetime not null, \`is_rain_enabled\` tinyint(1) not null default false, \`rain_percentage\` int not null default 0, \`is_fog_enabled\` tinyint(1) not null default false, \`fog_density\` int not null default 0, primary key (\`date\`)) default character set utf8mb4 engine = InnoDB;`);
 
-    this.addSql(`create table \`zone_event_tile\` (\`id\` varchar(255) not null, \`zone_id\` varchar(255) not null, \`type\` enum('BLOCK', 'TELEPORT', 'NPC', 'ITEM') not null, \`position_x\` int not null, \`position_y\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
-    this.addSql(`alter table \`zone_event_tile\` add index \`zone_event_tile_zone_id_index\`(\`zone_id\`);`);
+    this.addSql(`alter table \`map_effect\` add constraint \`map_effect_map_id_foreign\` foreign key (\`map_id\`) references \`map\` (\`id\`) on update cascade on delete cascade;`);
 
-    this.addSql(`create table \`zone_event_tile_teleport\` (\`id\` varchar(255) not null, \`zone_event_tile_id\` varchar(255) not null, \`to_zone_id\` varchar(255) not null, \`to_rotation\` int not null, \`to_position_x\` int not null, \`to_position_y\` int not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
-    this.addSql(`alter table \`zone_event_tile_teleport\` add unique \`zone_event_tile_teleport_zone_event_tile_id_unique\`(\`zone_event_tile_id\`);`);
-    this.addSql(`alter table \`zone_event_tile_teleport\` add index \`zone_event_tile_teleport_to_zone_id_index\`(\`to_zone_id\`);`);
+    this.addSql(`alter table \`map_event_tile\` add constraint \`map_event_tile_map_id_foreign\` foreign key (\`map_id\`) references \`map\` (\`id\`) on update cascade on delete cascade;`);
 
-    this.addSql(`create table \`zone_object\` (\`id\` varchar(255) not null, \`zone_id\` varchar(255) not null, \`map_object_id\` varchar(255) not null, \`depth\` int not null default 0, \`is_rotated\` tinyint(1) not null default false, \`position_x\` int not null default 0, \`position_y\` int not null default 0, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
-    this.addSql(`alter table \`zone_object\` add index \`zone_object_zone_id_index\`(\`zone_id\`);`);
-    this.addSql(`alter table \`zone_object\` add index \`zone_object_map_object_id_index\`(\`map_object_id\`);`);
+    this.addSql(`alter table \`map_event_tile_teleport\` add constraint \`map_event_tile_teleport_map_event_tile_id_foreign\` foreign key (\`map_event_tile_id\`) references \`map_event_tile\` (\`id\`) on update cascade on delete cascade;`);
+    this.addSql(`alter table \`map_event_tile_teleport\` add constraint \`map_event_tile_teleport_to_map_id_foreign\` foreign key (\`to_map_id\`) references \`map\` (\`id\`) on update cascade on delete cascade;`);
+
+    this.addSql(`alter table \`placed_map_object\` add constraint \`placed_map_object_map_id_foreign\` foreign key (\`map_id\`) references \`map\` (\`id\`) on update cascade on delete cascade;`);
+    this.addSql(`alter table \`placed_map_object\` add constraint \`placed_map_object_map_object_id_foreign\` foreign key (\`map_object_id\`) references \`map_object\` (\`id\`) on update cascade on delete cascade;`);
 
     this.addSql(`alter table \`item\` add constraint \`item_sprite_id_foreign\` foreign key (\`sprite_id\`) references \`sprite\` (\`id\`) on update cascade on delete set null;`);
 
@@ -77,28 +87,18 @@ export class Migration20250101224501 extends Migration {
     this.addSql(`alter table \`password_reset_token\` add constraint \`password_reset_token_user_id_foreign\` foreign key (\`user_id\`) references \`user\` (\`id\`) on update cascade on delete cascade;`);
 
     this.addSql(`alter table \`character\` add constraint \`character_user_id_foreign\` foreign key (\`user_id\`) references \`user\` (\`id\`) on update cascade on delete cascade;`);
-    this.addSql(`alter table \`character\` add constraint \`character_zone_id_foreign\` foreign key (\`zone_id\`) references \`zone\` (\`id\`) on update cascade;`);
+    this.addSql(`alter table \`character\` add constraint \`character_map_id_foreign\` foreign key (\`map_id\`) references \`map\` (\`id\`) on update cascade;`);
     this.addSql(`alter table \`character\` add constraint \`character_character_type_id_foreign\` foreign key (\`character_type_id\`) references \`character_type\` (\`id\`) on update cascade on delete set null;`);
     this.addSql(`alter table \`character\` add constraint \`character_character_hair_id_foreign\` foreign key (\`character_hair_id\`) references \`character_hair\` (\`id\`) on update cascade on delete set null;`);
 
     this.addSql(`alter table \`chat\` add constraint \`chat_character_id_foreign\` foreign key (\`character_id\`) references \`character\` (\`id\`) on update cascade on delete cascade;`);
-    this.addSql(`alter table \`chat\` add constraint \`chat_zone_id_foreign\` foreign key (\`zone_id\`) references \`zone\` (\`id\`) on update cascade on delete cascade;`);
+    this.addSql(`alter table \`chat\` add constraint \`chat_map_id_foreign\` foreign key (\`map_id\`) references \`map\` (\`id\`) on update cascade on delete cascade;`);
 
     this.addSql(`alter table \`character_item\` add constraint \`character_item_character_id_foreign\` foreign key (\`character_id\`) references \`character\` (\`id\`) on update cascade on delete cascade;`);
     this.addSql(`alter table \`character_item\` add constraint \`character_item_item_id_foreign\` foreign key (\`item_id\`) references \`item\` (\`id\`) on update cascade on delete cascade;`);
 
     this.addSql(`alter table \`character_equipment\` add constraint \`character_equipment_character_id_foreign\` foreign key (\`character_id\`) references \`character\` (\`id\`) on update cascade on delete cascade;`);
     this.addSql(`alter table \`character_equipment\` add constraint \`character_equipment_character_item_id_foreign\` foreign key (\`character_item_id\`) references \`character_item\` (\`id\`) on update cascade on delete cascade;`);
-
-    this.addSql(`alter table \`zone_effect\` add constraint \`zone_effect_zone_id_foreign\` foreign key (\`zone_id\`) references \`zone\` (\`id\`) on update cascade on delete cascade;`);
-
-    this.addSql(`alter table \`zone_event_tile\` add constraint \`zone_event_tile_zone_id_foreign\` foreign key (\`zone_id\`) references \`zone\` (\`id\`) on update cascade on delete cascade;`);
-
-    this.addSql(`alter table \`zone_event_tile_teleport\` add constraint \`zone_event_tile_teleport_zone_event_tile_id_foreign\` foreign key (\`zone_event_tile_id\`) references \`zone_event_tile\` (\`id\`) on update cascade on delete cascade;`);
-    this.addSql(`alter table \`zone_event_tile_teleport\` add constraint \`zone_event_tile_teleport_to_zone_id_foreign\` foreign key (\`to_zone_id\`) references \`zone\` (\`id\`) on update cascade on delete cascade;`);
-
-    this.addSql(`alter table \`zone_object\` add constraint \`zone_object_zone_id_foreign\` foreign key (\`zone_id\`) references \`zone\` (\`id\`) on update cascade on delete cascade;`);
-    this.addSql(`alter table \`zone_object\` add constraint \`zone_object_map_object_id_foreign\` foreign key (\`map_object_id\`) references \`map_object\` (\`id\`) on update cascade on delete cascade;`);
   }
 
 }
diff --git a/package-lock.json b/package-lock.json
index 8ab468a..342c54e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3179,15 +3179,16 @@
       }
     },
     "node_modules/es-set-tostringtag": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
-      "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "get-intrinsic": "^1.2.4",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
         "has-tostringtag": "^1.0.2",
-        "hasown": "^2.0.1"
+        "hasown": "^2.0.2"
       },
       "engines": {
         "node": ">= 0.4"
diff --git a/src/application/enums.ts b/src/application/enums.ts
index d347a4c..b4609cc 100644
--- a/src/application/enums.ts
+++ b/src/application/enums.ts
@@ -55,7 +55,7 @@ export enum CharacterEquipmentSlotType {
   RING = 'RING'
 }
 
-export enum ZoneEventTileType {
+export enum MapEventTileType {
   BLOCK = 'BLOCK',
   TELEPORT = 'TELEPORT',
   NPC = 'NPC',
diff --git a/src/application/types.ts b/src/application/types.ts
index 5dda62a..f6aa12b 100644
--- a/src/application/types.ts
+++ b/src/application/types.ts
@@ -1,8 +1,8 @@
 import { Server, Socket } from 'socket.io'
 
 import { Character } from '#entities/character'
-import { ZoneEventTile } from '#entities/zoneEventTile'
-import { ZoneEventTileTeleport } from '#entities/zoneEventTileTeleport'
+import { MapEventTile } from '#entities/mapEventTile'
+import { MapEventTileTeleport } from '#entities/mapEventTileTeleport'
 
 export type UUID = `${string}-${string}-${string}-${string}-${string}`
 
@@ -26,8 +26,8 @@ export type ExtendedCharacter = Character & {
   resetMovement?: boolean
 }
 
-export type ZoneEventTileWithTeleport = ZoneEventTile & {
-  teleport: ZoneEventTileTeleport
+export type MapEventTileWithTeleport = MapEventTile & {
+  teleport: MapEventTileTeleport
 }
 
 export type AssetData = {
diff --git a/src/commands/init.ts b/src/commands/init.ts
index 088d56d..0944155 100644
--- a/src/commands/init.ts
+++ b/src/commands/init.ts
@@ -14,11 +14,11 @@ import { Sprite } from '#entities/sprite'
 import { SpriteAction } from '#entities/spriteAction'
 import { Tile } from '#entities/tile'
 import { User } from '#entities/user'
-import { Zone } from '#entities/zone'
-import { ZoneEffect } from '#entities/zoneEffect'
+import { Map } from '#entities/map'
+import { MapEffect } from '#entities/mapEffect'
 import CharacterHairRepository from '#repositories/characterHairRepository'
 import CharacterTypeRepository from '#repositories/characterTypeRepository'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapRepository from '#repositories/mapRepository'
 
 // @TODO : Replace this with seeding
 // https://mikro-orm.io/docs/seeding
@@ -32,8 +32,8 @@ export default class InitCommand extends BaseCommand {
     await this.createCharacterHair()
     // await this.createCharacterEquipment()
 
-    // Zone
-    await this.createZone()
+    // Map
+    await this.createMap()
 
     // User
     await this.createUser()
@@ -224,17 +224,17 @@ export default class InitCommand extends BaseCommand {
     await equipmentSprite.save()
   }
 
-  private async createZone(): Promise<void> {
-    const zone = new Zone()
-    await zone
-      .setName('New zone')
+  private async createMap(): Promise<void> {
+    const map = new Map()
+    await map
+      .setName('New map')
       .setWidth(100)
       .setHeight(100)
       .setTiles(Array.from({ length: 100 }, () => Array.from({ length: 100 }, () => 'a2fd8d6f-5042-437a-9c1e-c66b91ecc35b')))
       .save()
 
-    const effect = new ZoneEffect()
-    await effect.setEffect('light').setStrength(100).setZone(zone).save()
+    const effect = new MapEffect()
+    await effect.setEffect('light').setStrength(100).setMap(map).save()
   }
 
   private async createUser(): Promise<void> {
@@ -247,7 +247,7 @@ export default class InitCommand extends BaseCommand {
       .setUser(user)
       .setName('root')
       .setRole('gm')
-      .setZone((await ZoneRepository.getFirst())!)
+      .setMap((await MapRepository.getFirst())!)
       .setCharacterType((await CharacterTypeRepository.getFirst()) ?? undefined)
       .setCharacterHair((await CharacterHairRepository.getFirst()) ?? undefined)
       .save()
diff --git a/src/commands/listZones.ts b/src/commands/listMaps.ts
similarity index 53%
rename from src/commands/listZones.ts
rename to src/commands/listMaps.ts
index 8a56ab7..0f8e474 100644
--- a/src/commands/listZones.ts
+++ b/src/commands/listMaps.ts
@@ -1,12 +1,12 @@
 import { Server } from 'socket.io'
 
 import { BaseCommand } from '#application/base/baseCommand'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 
 type CommandInput = string[]
 
-export default class ListZonesCommand extends BaseCommand {
+export default class ListMapsCommand extends BaseCommand {
   public execute(input: CommandInput): void {
-    console.log(ZoneManager.getLoadedZones())
+    console.log(MapManager.getLoadedMaps())
   }
 }
diff --git a/src/entities/character.ts b/src/entities/character.ts
index 3cd393c..46e2f4f 100644
--- a/src/entities/character.ts
+++ b/src/entities/character.ts
@@ -8,7 +8,7 @@ import { CharacterItem } from './characterItem'
 import { CharacterType } from './characterType'
 import { Chat } from './chat'
 import { User } from './user'
-import { Zone } from './zone'
+import { Map } from './map'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
@@ -35,7 +35,7 @@ export class Character extends BaseEntity {
 
   // Position
   @ManyToOne()
-  zone!: Zone // @TODO: Update to spawn point when current zone is not found
+  map!: Map // @TODO: Update to spawn point when current map is not found
 
   @Property()
   positionX = 0
@@ -142,13 +142,13 @@ export class Character extends BaseEntity {
     return this.chats
   }
 
-  setZone(zone: Zone) {
-    this.zone = zone
+  setMap(map: Map) {
+    this.map = map
     return this
   }
 
-  getZone() {
-    return this.zone
+  getMap() {
+    return this.map
   }
 
   setPositionX(positionX: number) {
diff --git a/src/entities/chat.ts b/src/entities/chat.ts
index 680d541..7417640 100644
--- a/src/entities/chat.ts
+++ b/src/entities/chat.ts
@@ -3,7 +3,7 @@ import { randomUUID } from 'node:crypto'
 import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'
 
 import { Character } from './character'
-import { Zone } from './zone'
+import { Map } from './map'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
@@ -17,7 +17,7 @@ export class Chat extends BaseEntity {
   character!: Character
 
   @ManyToOne({ deleteRule: 'cascade' })
-  zone!: Zone
+  map!: Map
 
   @Property()
   message!: string
@@ -43,13 +43,13 @@ export class Chat extends BaseEntity {
     return this.character
   }
 
-  setZone(zone: Zone) {
-    this.zone = zone
+  setMap(map: Map) {
+    this.map = map
     return this
   }
 
-  getZone() {
-    return this.zone
+  getMap() {
+    return this.map
   }
 
   setMessage(message: string) {
diff --git a/src/entities/zone.ts b/src/entities/map.ts
similarity index 57%
rename from src/entities/zone.ts
rename to src/entities/map.ts
index 91c9f26..acb92f9 100644
--- a/src/entities/zone.ts
+++ b/src/entities/map.ts
@@ -4,16 +4,16 @@ import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/
 
 import { Character } from './character'
 import { Chat } from './chat'
-import { ZoneEffect } from './zoneEffect'
-import { ZoneEventTile } from './zoneEventTile'
-import { ZoneEventTileTeleport } from './zoneEventTileTeleport'
-import { ZoneObject } from './zoneObject'
+import { MapEffect } from './mapEffect'
+import { MapEventTile } from './mapEventTile'
+import { MapEventTileTeleport } from './mapEventTileTeleport'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
+import { placedMapObject } from '#entities/placedMapObject'
 
 @Entity()
-export class Zone extends BaseEntity {
+export class Map extends BaseEntity {
   @PrimaryKey()
   id = randomUUID()
 
@@ -38,22 +38,22 @@ export class Zone extends BaseEntity {
   @Property()
   updatedAt = new Date()
 
-  @OneToMany(() => ZoneEffect, (effect) => effect.zone)
-  zoneEffects = new Collection<ZoneEffect>(this)
+  @OneToMany(() => MapEffect, (effect) => effect.map)
+  mapEffects = new Collection<MapEffect>(this)
 
-  @OneToMany(() => ZoneEventTile, (tile) => tile.zone)
-  zoneEventTiles = new Collection<ZoneEventTile>(this)
+  @OneToMany(() => MapEventTile, (tile) => tile.map)
+  mapEventTiles = new Collection<MapEventTile>(this)
 
-  @OneToMany(() => ZoneEventTileTeleport, (teleport) => teleport.toZone)
-  zoneEventTileTeleports = new Collection<ZoneEventTileTeleport>(this)
+  @OneToMany(() => MapEventTileTeleport, (teleport) => teleport.toMap)
+  mapEventTileTeleports = new Collection<MapEventTileTeleport>(this)
 
-  @OneToMany(() => ZoneObject, (object) => object.zone)
-  zoneObjects = new Collection<ZoneObject>(this)
+  @OneToMany(() => placedMapObject, (object) => object.map)
+  placedMapObjects = new Collection<placedMapObject>(this)
 
-  @OneToMany(() => Character, (character) => character.zone)
+  @OneToMany(() => Character, (character) => character.map)
   characters = new Collection<Character>(this)
 
-  @OneToMany(() => Chat, (chat) => chat.zone)
+  @OneToMany(() => Chat, (chat) => chat.map)
   chats = new Collection<Chat>(this)
 
   setId(id: UUID) {
@@ -128,40 +128,40 @@ export class Zone extends BaseEntity {
     return this.updatedAt
   }
 
-  setZoneEffects(zoneEffects: Collection<ZoneEffect>) {
-    this.zoneEffects = zoneEffects
+  setMapEffects(mapEffects: Collection<MapEffect>) {
+    this.mapEffects = mapEffects
     return this
   }
 
-  getZoneEffects() {
-    return this.zoneEffects
+  getMapEffects() {
+    return this.mapEffects
   }
 
-  setZoneEventTiles(zoneEventTiles: Collection<ZoneEventTile>) {
-    this.zoneEventTiles = zoneEventTiles
+  setMapEventTiles(mapEventTiles: Collection<MapEventTile>) {
+    this.mapEventTiles = mapEventTiles
     return this
   }
 
-  getZoneEventTiles() {
-    return this.zoneEventTiles
+  getMapEventTiles() {
+    return this.mapEventTiles
   }
 
-  setZoneEventTileTeleports(zoneEventTileTeleports: Collection<ZoneEventTileTeleport>) {
-    this.zoneEventTileTeleports = zoneEventTileTeleports
+  setMapEventTileTeleports(mapEventTileTeleports: Collection<MapEventTileTeleport>) {
+    this.mapEventTileTeleports = mapEventTileTeleports
     return this
   }
 
-  getZoneEventTileTeleports() {
-    return this.zoneEventTileTeleports
+  getMapEventTileTeleports() {
+    return this.mapEventTileTeleports
   }
 
-  setZoneObjects(zoneObjects: Collection<ZoneObject>) {
-    this.zoneObjects = zoneObjects
+  setPlacedMapObjects(placedMapObjects: Collection<placedMapObject>) {
+    this.placedMapObjects = placedMapObjects
     return this
   }
 
-  getZoneObjects() {
-    return this.zoneObjects
+  getPlacedMapObjects() {
+    return this.placedMapObjects
   }
 
   setCharacters(characters: Collection<Character>) {
diff --git a/src/entities/zoneEffect.ts b/src/entities/mapEffect.ts
similarity index 81%
rename from src/entities/zoneEffect.ts
rename to src/entities/mapEffect.ts
index ff3ff64..73ad517 100644
--- a/src/entities/zoneEffect.ts
+++ b/src/entities/mapEffect.ts
@@ -2,18 +2,18 @@ import { randomUUID } from 'node:crypto'
 
 import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'
 
-import { Zone } from './zone'
+import { Map } from './map'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
 
 @Entity()
-export class ZoneEffect extends BaseEntity {
+export class MapEffect extends BaseEntity {
   @PrimaryKey()
   id = randomUUID()
 
   @ManyToOne({ deleteRule: 'cascade' })
-  zone!: Zone
+  map!: Map
 
   @Property()
   effect!: string
@@ -30,13 +30,13 @@ export class ZoneEffect extends BaseEntity {
     return this.id
   }
 
-  setZone(zone: Zone) {
-    this.zone = zone
+  setMap(map: Map) {
+    this.map = map
     return this
   }
 
-  getZone() {
-    return this.zone
+  getMap() {
+    return this.map
   }
 
   setEffect(effect: string) {
diff --git a/src/entities/zoneEventTile.ts b/src/entities/mapEventTile.ts
similarity index 63%
rename from src/entities/zoneEventTile.ts
rename to src/entities/mapEventTile.ts
index 13951c5..3e33b2e 100644
--- a/src/entities/zoneEventTile.ts
+++ b/src/entities/mapEventTile.ts
@@ -2,23 +2,23 @@ import { randomUUID } from 'node:crypto'
 
 import { Entity, Enum, ManyToOne, OneToOne, PrimaryKey, Property } from '@mikro-orm/core'
 
-import { Zone } from './zone'
-import { ZoneEventTileTeleport } from './zoneEventTileTeleport'
+import { Map } from './map'
+import { MapEventTileTeleport } from './mapEventTileTeleport'
 
 import { BaseEntity } from '#application/base/baseEntity'
-import { ZoneEventTileType } from '#application/enums'
+import { MapEventTileType } from '#application/enums'
 import { UUID } from '#application/types'
 
 @Entity()
-export class ZoneEventTile extends BaseEntity {
+export class MapEventTile extends BaseEntity {
   @PrimaryKey()
   id = randomUUID()
 
   @ManyToOne({ deleteRule: 'cascade' })
-  zone!: Zone
+  map!: Map
 
-  @Enum(() => ZoneEventTileType)
-  type!: ZoneEventTileType
+  @Enum(() => MapEventTileType)
+  type!: MapEventTileType
 
   @Property()
   positionX!: number
@@ -26,8 +26,8 @@ export class ZoneEventTile extends BaseEntity {
   @Property()
   positionY!: number
 
-  @OneToOne(() => ZoneEventTileTeleport, (teleport) => teleport.zoneEventTile)
-  teleport?: ZoneEventTileTeleport
+  @OneToOne(() => MapEventTileTeleport, (teleport) => teleport.mapEventTile)
+  teleport?: MapEventTileTeleport
 
   setId(id: UUID) {
     this.id = id
@@ -38,16 +38,16 @@ export class ZoneEventTile extends BaseEntity {
     return this.id
   }
 
-  setZone(zone: Zone) {
-    this.zone = zone
+  setMap(map: Map) {
+    this.map = map
     return this
   }
 
-  getZone() {
-    return this.zone
+  getMap() {
+    return this.map
   }
 
-  setType(type: ZoneEventTileType) {
+  setType(type: MapEventTileType) {
     this.type = type
     return this
   }
@@ -74,7 +74,7 @@ export class ZoneEventTile extends BaseEntity {
     return this.positionY
   }
 
-  setTeleport(teleport: ZoneEventTileTeleport) {
+  setTeleport(teleport: MapEventTileTeleport) {
     this.teleport = teleport
     return this
   }
diff --git a/src/entities/zoneEventTileTeleport.ts b/src/entities/mapEventTileTeleport.ts
similarity index 71%
rename from src/entities/zoneEventTileTeleport.ts
rename to src/entities/mapEventTileTeleport.ts
index d87f375..1d62b97 100644
--- a/src/entities/zoneEventTileTeleport.ts
+++ b/src/entities/mapEventTileTeleport.ts
@@ -2,22 +2,22 @@ import { randomUUID } from 'node:crypto'
 
 import { Entity, ManyToOne, OneToOne, PrimaryKey, Property } from '@mikro-orm/core'
 
-import { Zone } from './zone'
-import { ZoneEventTile } from './zoneEventTile'
+import { Map } from './map'
+import { MapEventTile } from './mapEventTile'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
 
 @Entity()
-export class ZoneEventTileTeleport extends BaseEntity {
+export class MapEventTileTeleport extends BaseEntity {
   @PrimaryKey()
   id = randomUUID()
 
   @OneToOne({ deleteRule: 'cascade' })
-  zoneEventTile!: ZoneEventTile
+  mapEventTile!: MapEventTile
 
   @ManyToOne({ deleteRule: 'cascade' })
-  toZone!: Zone
+  toMap!: Map
 
   @Property()
   toRotation!: number
@@ -37,22 +37,22 @@ export class ZoneEventTileTeleport extends BaseEntity {
     return this.id
   }
 
-  setZoneEventTile(zoneEventTile: ZoneEventTile) {
-    this.zoneEventTile = zoneEventTile
+  setMapEventTile(mapEventTile: MapEventTile) {
+    this.mapEventTile = mapEventTile
     return this
   }
 
-  getZoneEventTile() {
-    return this.zoneEventTile
+  getMapEventTile() {
+    return this.mapEventTile
   }
 
-  setToZone(toZone: Zone) {
-    this.toZone = toZone
+  setToMap(toMap: Map) {
+    this.toMap = toMap
     return this
   }
 
-  getToZone() {
-    return this.toZone
+  getToMap() {
+    return this.toMap
   }
 
   setToRotation(toRotation: number) {
diff --git a/src/entities/mapObject.ts b/src/entities/mapObject.ts
index 385bbd0..a59d8e6 100644
--- a/src/entities/mapObject.ts
+++ b/src/entities/mapObject.ts
@@ -1,8 +1,6 @@
 import { randomUUID } from 'node:crypto'
 
-import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'
-
-import { ZoneObject } from './zoneObject'
+import { Entity, PrimaryKey, Property } from '@mikro-orm/core'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
diff --git a/src/entities/zoneObject.ts b/src/entities/placedMapObject.ts
similarity index 88%
rename from src/entities/zoneObject.ts
rename to src/entities/placedMapObject.ts
index f71854a..2c929f4 100644
--- a/src/entities/zoneObject.ts
+++ b/src/entities/placedMapObject.ts
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto'
 
 import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'
 
-import { Zone } from './zone'
+import { Map } from './map'
 
 import { BaseEntity } from '#application/base/baseEntity'
 import { UUID } from '#application/types'
@@ -10,12 +10,12 @@ import { MapObject } from '#entities/mapObject'
 
 //@TODO : Rename mapObject
 @Entity()
-export class ZoneObject extends BaseEntity {
+export class placedMapObject extends BaseEntity {
   @PrimaryKey()
   id = randomUUID()
 
   @ManyToOne({ deleteRule: 'cascade' })
-  zone!: Zone
+  map!: Map
 
   @ManyToOne({ deleteRule: 'cascade' })
   mapObject!: MapObject
@@ -41,13 +41,13 @@ export class ZoneObject extends BaseEntity {
     return this.id
   }
 
-  setZone(zone: Zone) {
-    this.zone = zone
+  setMap(map: Map) {
+    this.map = map
     return this
   }
 
-  getZone() {
-    return this.zone
+  getMap() {
+    return this.map
   }
 
   setMapObject(mapObject: MapObject) {
diff --git a/src/events/character/connect.ts b/src/events/character/connect.ts
index accea3c..d4e421e 100644
--- a/src/events/character/connect.ts
+++ b/src/events/character/connect.ts
@@ -1,6 +1,6 @@
 import { BaseEvent } from '#application/base/baseEvent'
 import { UUID } from '#application/types'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 import CharacterHairRepository from '#repositories/characterHairRepository'
 import CharacterRepository from '#repositories/characterRepository'
 import TeleportService from '#services/teleportService'
@@ -61,7 +61,7 @@ export default class CharacterConnectEvent extends BaseEvent {
       await new Promise((resolve) => setTimeout(resolve, 100))
 
       await TeleportService.teleportCharacter(character.id, {
-        targetZoneId: character.zone.id,
+        targetMapId: character.map.id,
         targetX: character.positionX,
         targetY: character.positionY,
         rotation: character.rotation,
@@ -75,6 +75,6 @@ export default class CharacterConnectEvent extends BaseEvent {
 
   private async checkForActiveCharacters(): Promise<boolean> {
     const characters = await CharacterRepository.getByUserId(this.socket.userId!)
-    return characters?.some((char) => ZoneManager.getCharacterById(char.id)) ?? false
+    return characters?.some((char) => MapManager.getCharacterById(char.id)) ?? false
   }
 }
diff --git a/src/events/character/create.ts b/src/events/character/create.ts
index e613477..f343559 100644
--- a/src/events/character/create.ts
+++ b/src/events/character/create.ts
@@ -5,7 +5,7 @@ import { ZCharacterCreate } from '#application/zodTypes'
 import { Character } from '#entities/character'
 import CharacterRepository from '#repositories/characterRepository'
 import UserRepository from '#repositories/userRepository'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapRepository from '#repositories/mapRepository'
 
 export default class CharacterCreateEvent extends BaseEvent {
   public listen(): void {
@@ -37,10 +37,10 @@ export default class CharacterCreateEvent extends BaseEvent {
       }
 
       // @TODO: Change to default location
-      const zone = await ZoneRepository.getFirst()
+      const map = await MapRepository.getFirst()
 
       const newCharacter = new Character()
-      await newCharacter.setName(data.name).setUser(user).setZone(zone!).save()
+      await newCharacter.setName(data.name).setUser(user).setMap(map!).save()
 
       if (!newCharacter) {
         return this.socket.emit('notification', { message: 'Failed to create character. Please try again (later).' })
diff --git a/src/events/character/delete.ts b/src/events/character/delete.ts
index 2a558cd..ccb0ac0 100644
--- a/src/events/character/delete.ts
+++ b/src/events/character/delete.ts
@@ -1,7 +1,7 @@
 import { BaseEvent } from '#application/base/baseEvent'
 import { UUID } from '#application/types'
 import { Character } from '#entities/character'
-import { Zone } from '#entities/zone'
+import { Map } from '#entities/map'
 import CharacterRepository from '#repositories/characterRepository'
 
 type TypePayload = {
@@ -9,7 +9,7 @@ type TypePayload = {
 }
 
 type TypeResponse = {
-  zone: Zone
+  map: Map
   characters: Character[]
 }
 
diff --git a/src/events/chat/gameMaster/teleportCommand.ts b/src/events/chat/gameMaster/teleportCommand.ts
index e969d54..a0a8714 100644
--- a/src/events/chat/gameMaster/teleportCommand.ts
+++ b/src/events/chat/gameMaster/teleportCommand.ts
@@ -1,7 +1,7 @@
 import { BaseEvent } from '#application/base/baseEvent'
 import { UUID } from '#application/types'
-import ZoneManager from '#managers/zoneManager'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapManager from '#managers/mapManager'
+import MapRepository from '#repositories/mapRepository'
 import ChatService from '#services/chatService'
 import TeleportService from '#services/teleportService'
 
@@ -16,13 +16,13 @@ export default class TeleportCommandEvent extends BaseEvent {
 
   private async handleEvent(data: TypePayload, callback: (response: boolean) => void) {
     try {
-      const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
-      if (!zoneCharacter) {
+      const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
+      if (!mapCharacter) {
         this.logger.error('chat:message error', 'Character not found')
         return
       }
 
-      const character = zoneCharacter.character
+      const character = mapCharacter.character
 
       if (character.role !== 'gm') {
         this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
@@ -36,16 +36,16 @@ export default class TeleportCommandEvent extends BaseEvent {
       if (!args || args.length === 0 || args.length > 3) {
         this.socket.emit('notification', {
           title: 'Server message',
-          message: 'Usage: /teleport <zoneId> [x] [y]'
+          message: 'Usage: /teleport <mapId> [x] [y]'
         })
         return
       }
 
-      const zoneId = args[0] as UUID
+      const mapId = args[0] as UUID
       const targetX = args[1] ? parseInt(args[1], 10) : 0
       const targetY = args[2] ? parseInt(args[2], 10) : 0
 
-      if (!zoneId || isNaN(targetX) || isNaN(targetY)) {
+      if (!mapId || isNaN(targetX) || isNaN(targetY)) {
         this.socket.emit('notification', {
           title: 'Server message',
           message: 'Invalid parameters. X and Y coordinates must be numbers.'
@@ -53,16 +53,16 @@ export default class TeleportCommandEvent extends BaseEvent {
         return
       }
 
-      const zone = await ZoneRepository.getById(zoneId)
-      if (!zone) {
+      const map = await MapRepository.getById(mapId)
+      if (!map) {
         this.socket.emit('notification', {
           title: 'Server message',
-          message: 'Zone not found'
+          message: 'Map not found'
         })
         return
       }
 
-      if (character.zone.id === zone.id && targetX === character.positionX && targetY === character.positionY) {
+      if (character.map.id === map.id && targetX === character.positionX && targetY === character.positionY) {
         this.socket.emit('notification', {
           title: 'Server message',
           message: 'You are already at that location'
@@ -71,7 +71,7 @@ export default class TeleportCommandEvent extends BaseEvent {
       }
 
       const success = await TeleportService.teleportCharacter(character.id, {
-        targetZoneId: zone.id,
+        targetMapId: map.id,
         targetX,
         targetY,
         rotation: character.rotation
@@ -86,9 +86,9 @@ export default class TeleportCommandEvent extends BaseEvent {
 
       this.socket.emit('notification', {
         title: 'Server message',
-        message: `Teleported to ${zone.name} (${targetX}, ${targetY})`
+        message: `Teleported to ${map.name} (${targetX}, ${targetY})`
       })
-      this.logger.info('teleport', `Character ${character.id} teleported to zone ${zone.id} at position (${targetX}, ${targetY})`)
+      this.logger.info('teleport', `Character ${character.id} teleported to map ${map.id} at position (${targetX}, ${targetY})`)
     } catch (error: any) {
       this.logger.error(`Error in teleport command: ${error.message}`)
       this.socket.emit('notification', {
diff --git a/src/events/chat/message.ts b/src/events/chat/message.ts
index 13a27f9..7946032 100644
--- a/src/events/chat/message.ts
+++ b/src/events/chat/message.ts
@@ -1,6 +1,6 @@
 import { BaseEvent } from '#application/base/baseEvent'
-import ZoneManager from '#managers/zoneManager'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapManager from '#managers/mapManager'
+import MapRepository from '#repositories/mapRepository'
 import ChatService from '#services/chatService'
 
 type TypePayload = {
@@ -18,21 +18,21 @@ export default class ChatMessageEvent extends BaseEvent {
         return callback(false)
       }
 
-      const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
-      if (!zoneCharacter) {
+      const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
+      if (!mapCharacter) {
         this.logger.error('chat:message error', 'Character not found')
         return callback(false)
       }
 
-      const character = zoneCharacter.character
+      const character = mapCharacter.character
 
-      const zone = await ZoneRepository.getById(character.zone.id)
-      if (!zone) {
-        this.logger.error('chat:message error', 'Zone not found')
+      const map = await MapRepository.getById(character.map.id)
+      if (!map) {
+        this.logger.error('chat:message error', 'Map not found')
         return callback(false)
       }
 
-      if (await ChatService.sendZoneMessage(character.getId(), zone.getId(), data.message)) {
+      if (await ChatService.sendMapMessage(character.getId(), map.getId(), data.message)) {
         return callback(true)
       }
 
diff --git a/src/events/disconnect.ts b/src/events/disconnect.ts
index 8bb7e9c..fc2c912 100644
--- a/src/events/disconnect.ts
+++ b/src/events/disconnect.ts
@@ -1,5 +1,5 @@
 import { BaseEvent } from '#application/base/baseEvent'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 
 export default class DisconnectEvent extends BaseEvent {
   public listen(): void {
@@ -15,13 +15,13 @@ export default class DisconnectEvent extends BaseEvent {
 
       this.io.emit('user:disconnect', this.socket.userId)
 
-      const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
-      if (!zoneCharacter) {
+      const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
+      if (!mapCharacter) {
         this.logger.info('User disconnected but had no character set')
         return
       }
 
-      await zoneCharacter.disconnect(this.socket, this.io)
+      await mapCharacter.disconnect(this.socket, this.io)
       this.logger.info('User disconnected along with their character')
     } catch (error: any) {
       this.logger.error('disconnect error: ' + error.message)
diff --git a/src/events/gameMaster/assetManager/object/list.ts b/src/events/gameMaster/assetManager/object/list.ts
index 60b3dc6..f9ed578 100644
--- a/src/events/gameMaster/assetManager/object/list.ts
+++ b/src/events/gameMaster/assetManager/object/list.ts
@@ -1,32 +1,18 @@
-import { Object } from '@prisma/client'
-import { Server } from 'socket.io'
-
-import { TSocket } from '#application/types'
-import characterRepository from '#repositories/characterRepository'
 import ObjectRepository from '#repositories/objectRepository'
+import { BaseEvent } from '#application/base/baseEvent'
 
 interface IPayload {}
 
-export default class ObjectListEvent {
-  constructor(
-    private readonly io: Server,
-    private readonly socket: TSocket
-  ) {}
-
+export default class ObjectListEvent extends BaseEvent{
   public listen(): void {
     this.socket.on('gm:object:list', this.handleEvent.bind(this))
   }
 
   private async handleEvent(data: IPayload, callback: (response: Object[]) => void): Promise<void> {
-    const character = await characterRepository.getById(this.socket.characterId as number)
-    if (!character) return callback([])
-
-    if (character.role !== 'gm') {
-      return callback([])
-    }
+    if (!(await this.isCharacterGM())) return
 
     // get all objects
     const objects = await ObjectRepository.getAll()
-    callback(objects)
+    return callback(objects)
   }
 }
diff --git a/src/events/gameMaster/assetManager/sprite/create.ts b/src/events/gameMaster/assetManager/sprite/create.ts
index 25103b0..4ca8877 100644
--- a/src/events/gameMaster/assetManager/sprite/create.ts
+++ b/src/events/gameMaster/assetManager/sprite/create.ts
@@ -1,16 +1,10 @@
 import fs from 'fs/promises'
 
-import { Server } from 'socket.io'
-
 import { BaseEvent } from '#application/base/baseEvent'
 import Storage from '#application/storage'
+import { Sprite } from '#entities/sprite'
 
 export default class SpriteCreateEvent extends BaseEvent {
-  constructor(
-    private readonly io: Server,
-    private readonly socket: TSocket
-  ) {}
-
   public listen(): void {
     this.socket.on('gm:sprite:create', this.handleEvent.bind(this))
   }
@@ -24,21 +18,19 @@ export default class SpriteCreateEvent extends BaseEvent {
       // Ensure the folder exists
       await fs.mkdir(public_folder, { recursive: true })
 
-      const sprite = await prisma.sprite.create({
-        data: {
-          name: 'New sprite'
-        }
-      })
+      const sprite = new Sprite()
+      await sprite.setName('New sprite').save()
+
       const uuid = sprite.id
 
       // Create folder with uuid
       const sprite_folder = Storage.getPublicPath('sprites', uuid)
       await fs.mkdir(sprite_folder, { recursive: true })
 
-      callback(true)
+      return callback(true)
     } catch (error) {
       console.error('Error creating sprite:', error)
-      callback(false)
+      return callback(false)
     }
   }
 }
diff --git a/src/events/gameMaster/zoneEditor/create.ts b/src/events/gameMaster/mapEditor/create.ts
similarity index 56%
rename from src/events/gameMaster/zoneEditor/create.ts
rename to src/events/gameMaster/mapEditor/create.ts
index 91857de..8b8b94a 100644
--- a/src/events/gameMaster/zoneEditor/create.ts
+++ b/src/events/gameMaster/mapEditor/create.ts
@@ -1,6 +1,6 @@
 import { BaseEvent } from '#application/base/baseEvent'
-import { Zone } from '#entities/zone'
-import ZoneRepository from '#repositories/zoneRepository'
+import { Map } from '#entities/map'
+import MapRepository from '#repositories/mapRepository'
 
 type Payload = {
   name: string
@@ -8,30 +8,30 @@ type Payload = {
   height: number
 }
 
-export default class ZoneCreateEvent extends BaseEvent {
+export default class MapCreateEvent extends BaseEvent {
   public listen(): void {
-    this.socket.on('gm:zone_editor:zone:create', this.handleEvent.bind(this))
+    this.socket.on('gm:map_editor:map:create', this.handleEvent.bind(this))
   }
 
-  private async handleEvent(data: Payload, callback: (response: Zone[]) => void): Promise<void> {
+  private async handleEvent(data: Payload, callback: (response: Map[]) => void): Promise<void> {
     try {
       if (!(await this.isCharacterGM())) return
 
-      this.logger.info(`User ${(await this.getCharacter())!.getId()} has created a new zone via zone editor.`)
+      this.logger.info(`User ${(await this.getCharacter())!.getId()} has created a new map via map editor.`)
 
-      const zone = new Zone()
-      await zone
+      const map = new Map()
+      await map
         .setName(data.name)
         .setWidth(data.width)
         .setHeight(data.height)
         .setTiles(Array.from({ length: data.height }, () => Array.from({ length: data.width }, () => 'blank_tile')))
         .save()
 
-      const zoneList = await ZoneRepository.getAll()
-      return callback(zoneList)
+      const mapList = await MapRepository.getAll()
+      return callback(mapList)
     } catch (error: any) {
-      this.logger.error('gm:zone_editor:zone:create error', error.message)
-      this.socket.emit('notification', { message: 'Failed to create zone.' })
+      this.logger.error('gm:map_editor:map:create error', error.message)
+      this.socket.emit('notification', { message: 'Failed to create map.' })
       return callback([])
     }
   }
diff --git a/src/events/gameMaster/mapEditor/delete.ts b/src/events/gameMaster/mapEditor/delete.ts
new file mode 100644
index 0000000..d4fb700
--- /dev/null
+++ b/src/events/gameMaster/mapEditor/delete.ts
@@ -0,0 +1,29 @@
+import { BaseEvent } from '#application/base/baseEvent'
+import { UUID } from '#application/types'
+import MapRepository from '#repositories/mapRepository'
+
+type Payload = {
+  mapId: UUID
+}
+
+export default class MapDeleteEvent extends BaseEvent {
+  public listen(): void {
+    this.socket.on('gm:map_editor:map:delete', this.handleEvent.bind(this))
+  }
+
+  private async handleEvent(data: Payload, callback: (response: boolean) => void): Promise<void> {
+    if (!(await this.isCharacterGM())) return
+
+    try {
+      this.logger.info(`Deleting map ${data.mapId}`)
+
+      await (await MapRepository.getById(data.mapId))?.delete()
+
+      this.logger.info(`Map ${data.mapId} deleted successfully.`)
+      return callback(true)
+    } catch (error: unknown) {
+      this.logger.error('gm:map_editor:map:delete error', error)
+      return callback(false)
+    }
+  }
+}
diff --git a/src/events/gameMaster/mapEditor/list.ts b/src/events/gameMaster/mapEditor/list.ts
new file mode 100644
index 0000000..8130643
--- /dev/null
+++ b/src/events/gameMaster/mapEditor/list.ts
@@ -0,0 +1,25 @@
+import { BaseEvent } from '#application/base/baseEvent'
+import { Map } from '#entities/map'
+import MapRepository from '#repositories/mapRepository'
+
+interface IPayload {}
+
+export default class MapListEvent extends BaseEvent {
+  public listen(): void {
+    this.socket.on('gm:map_editor:map:list', this.handleEvent.bind(this))
+  }
+
+  private async handleEvent(data: IPayload, callback: (response: Map[]) => void): Promise<void> {
+    try {
+      if (!(await this.isCharacterGM())) return
+
+      this.logger.info(`User ${(await this.getCharacter())!.getId()} has created a new map via map editor.`)
+
+      const maps = await MapRepository.getAll()
+      return callback(maps)
+    } catch (error: any) {
+      this.logger.error('gm:map_editor:map:list error', error.message)
+      return callback([])
+    }
+  }
+}
diff --git a/src/events/gameMaster/mapEditor/request.ts b/src/events/gameMaster/mapEditor/request.ts
new file mode 100644
index 0000000..9809e0a
--- /dev/null
+++ b/src/events/gameMaster/mapEditor/request.ts
@@ -0,0 +1,39 @@
+import { BaseEvent } from '#application/base/baseEvent'
+import { UUID } from '#application/types'
+import { Map } from '#entities/map'
+import MapRepository from '#repositories/mapRepository'
+
+interface IPayload {
+  mapId: UUID
+}
+
+export default class MapRequestEvent extends BaseEvent {
+  public listen(): void {
+    this.socket.on('gm:map_editor:map:request', this.handleEvent.bind(this))
+  }
+
+  private async handleEvent(data: IPayload, callback: (response: Map | null) => void): Promise<void> {
+    try {
+      if (!(await this.isCharacterGM())) return
+
+      this.logger.info(`User ${(await this.getCharacter())!.getId()} has requested map via map editor.`)
+
+      if (!data.mapId) {
+        this.logger.info(`User ${(await this.getCharacter())!.getId()} tried to request map but did not provide a map id.`)
+        return callback(null)
+      }
+
+      const map = await MapRepository.getById(data.mapId)
+
+      if (!map) {
+        this.logger.info(`User ${(await this.getCharacter())!.getId()} tried to request map ${data.mapId} but it does not exist.`)
+        return callback(null)
+      }
+
+      return callback(map)
+    } catch (error: any) {
+      this.logger.error('gm:map_editor:map:request error', error.message)
+      return callback(null)
+    }
+  }
+}
diff --git a/src/events/gameMaster/mapEditor/update.ts b/src/events/gameMaster/mapEditor/update.ts
new file mode 100644
index 0000000..6d95a2d
--- /dev/null
+++ b/src/events/gameMaster/mapEditor/update.ts
@@ -0,0 +1,132 @@
+import { BaseEvent } from '#application/base/baseEvent'
+import { MapEventTileType } from '#application/enums'
+import { UUID } from '#application/types'
+import { Map } from '#entities/map'
+import { MapEffect } from '#entities/mapEffect'
+import { MapEventTile } from '#entities/mapEventTile'
+import { MapEventTileTeleport } from '#entities/mapEventTileTeleport'
+import { MapObject } from '#entities/mapObject'
+import mapManager from '#managers/mapManager'
+import MapRepository from '#repositories/mapRepository'
+
+interface IPayload {
+  mapId: UUID
+  name: string
+  width: number
+  height: number
+  tiles: string[][]
+  pvp: boolean
+  mapEventTiles: {
+    type: MapEventTileType
+    positionX: number
+    positionY: number
+    teleport?: {
+      toMapId: UUID
+      toPositionX: number
+      toPositionY: number
+      toRotation: number
+    }
+  }[]
+  mapEffects: {
+    effect: string
+    strength: number
+  }[]
+  mapObjects: MapObject[]
+}
+
+export default class MapUpdateEvent extends BaseEvent {
+  public listen(): void {
+    this.socket.on('gm:map_editor:map:update', this.handleEvent.bind(this))
+  }
+
+  private async handleEvent(data: IPayload, callback: (response: Map | null) => void): Promise<void> {
+    try {
+      if (!(await this.isCharacterGM())) return
+
+      const character = await this.getCharacter()
+      this.logger.info(`User ${character!.getId()} has updated map via map editor.`)
+
+      if (!data.mapId) {
+        this.logger.info(`User ${character!.getId()} tried to update map but did not provide a map id.`)
+        return callback(null)
+      }
+
+      let map = await MapRepository.getById(data.mapId)
+
+      if (!map) {
+        this.logger.info(`User ${character!.getId()} tried to update map ${data.mapId} but it does not exist.`)
+        return callback(null)
+      }
+
+      // Validation logic remains the same
+      if (data.tiles.length > data.height) {
+        data.tiles = data.tiles.slice(0, data.height)
+      }
+      for (let i = 0; i < data.tiles.length; i++) {
+        if (data.tiles[i].length > data.width) {
+          data.tiles[i] = data.tiles[i].slice(0, data.width)
+        }
+      }
+
+      data.mapEventTiles = data.mapEventTiles.filter((tile) => tile.positionX >= 0 && tile.positionX < data.width && tile.positionY >= 0 && tile.positionY < data.height)
+
+      data.mapObjects = data.mapObjects.filter((obj) => obj.positionX >= 0 && obj.positionX < data.width && obj.positionY >= 0 && obj.positionY < data.height)
+
+      // Clear existing collections
+      map.mapEventTiles.removeAll()
+      map.mapObjects.removeAll()
+      map.mapEffects.removeAll()
+
+      // Create and add new map event tiles
+      for (const tile of data.mapEventTiles) {
+        const mapEventTile = new MapEventTile().setType(tile.type).setPositionX(tile.positionX).setPositionY(tile.positionY).setMap(map)
+
+        if (tile.teleport) {
+          const teleport = new MapEventTileTeleport()
+            .setToMap((await MapRepository.getById(tile.teleport.toMapId))!)
+            .setToPositionX(tile.teleport.toPositionX)
+            .setToPositionY(tile.teleport.toPositionY)
+            .setToRotation(tile.teleport.toRotation)
+
+          mapEventTile.setTeleport(teleport)
+        }
+
+        map.mapEventTiles.add(mapEventTile)
+      }
+
+      // Create and add new map objects
+      for (const object of data.mapObjects) {
+        const mapObject = new MapObject().setMapObject(object.mapObject).setDepth(object.depth).setIsRotated(object.isRotated).setPositionX(object.positionX).setPositionY(object.positionY).setMap(map)
+
+        map.mapObjects.add(mapObject)
+      }
+
+      // Create and add new map effects
+      for (const effect of data.mapEffects) {
+        const mapEffect = new MapEffect().setEffect(effect.effect).setStrength(effect.strength).setMap(map)
+
+        map.mapEffects.add(mapEffect)
+      }
+
+      // Update map properties
+      await map.setName(data.name).setWidth(data.width).setHeight(data.height).setTiles(data.tiles).setPvp(data.pvp).setUpdatedAt(new Date()).update()
+
+      // Reload map from database to get fresh data
+      map = await MapRepository.getById(data.mapId)
+
+      if (!map) {
+        this.logger.info(`User ${character!.getId()} tried to update map ${data.mapId} but it does not exist after update.`)
+        return callback(null)
+      }
+
+      // Reload map for players
+      mapManager.unloadMap(data.mapId)
+      await mapManager.loadMap(map)
+
+      return callback(map)
+    } catch (error: any) {
+      this.logger.error(`gm:map_editor:map:update error: ${error instanceof Error ? error.message : String(error)}`)
+      return callback(null)
+    }
+  }
+}
diff --git a/src/events/gameMaster/zoneEditor/delete.ts b/src/events/gameMaster/zoneEditor/delete.ts
deleted file mode 100644
index 44ac4e6..0000000
--- a/src/events/gameMaster/zoneEditor/delete.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { BaseEvent } from '#application/base/baseEvent'
-import { UUID } from '#application/types'
-import ZoneRepository from '#repositories/zoneRepository'
-
-type Payload = {
-  zoneId: UUID
-}
-
-export default class ZoneDeleteEvent extends BaseEvent {
-  public listen(): void {
-    this.socket.on('gm:zone_editor:zone:delete', this.handleEvent.bind(this))
-  }
-
-  private async handleEvent(data: Payload, callback: (response: boolean) => void): Promise<void> {
-    if (!(await this.isCharacterGM())) return
-
-    try {
-      this.logger.info(`Deleting zone ${data.zoneId}`)
-
-      await (await ZoneRepository.getById(data.zoneId))?.delete()
-
-      this.logger.info(`Zone ${data.zoneId} deleted successfully.`)
-      return callback(true)
-    } catch (error: unknown) {
-      this.logger.error('gm:zone_editor:zone:delete error', error)
-      return callback(false)
-    }
-  }
-}
diff --git a/src/events/gameMaster/zoneEditor/list.ts b/src/events/gameMaster/zoneEditor/list.ts
deleted file mode 100644
index 86c41c6..0000000
--- a/src/events/gameMaster/zoneEditor/list.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { BaseEvent } from '#application/base/baseEvent'
-import { Zone } from '#entities/zone'
-import ZoneRepository from '#repositories/zoneRepository'
-
-interface IPayload {}
-
-export default class ZoneListEvent extends BaseEvent {
-  public listen(): void {
-    this.socket.on('gm:zone_editor:zone:list', this.handleEvent.bind(this))
-  }
-
-  private async handleEvent(data: IPayload, callback: (response: Zone[]) => void): Promise<void> {
-    try {
-      if (!(await this.isCharacterGM())) return
-
-      this.logger.info(`User ${(await this.getCharacter())!.getId()} has created a new zone via zone editor.`)
-
-      const zones = await ZoneRepository.getAll()
-      return callback(zones)
-    } catch (error: any) {
-      this.logger.error('gm:zone_editor:zone:list error', error.message)
-      return callback([])
-    }
-  }
-}
diff --git a/src/events/gameMaster/zoneEditor/request.ts b/src/events/gameMaster/zoneEditor/request.ts
deleted file mode 100644
index 81895dd..0000000
--- a/src/events/gameMaster/zoneEditor/request.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { BaseEvent } from '#application/base/baseEvent'
-import { UUID } from '#application/types'
-import { Zone } from '#entities/zone'
-import ZoneRepository from '#repositories/zoneRepository'
-
-interface IPayload {
-  zoneId: UUID
-}
-
-export default class ZoneRequestEvent extends BaseEvent {
-  public listen(): void {
-    this.socket.on('gm:zone_editor:zone:request', this.handleEvent.bind(this))
-  }
-
-  private async handleEvent(data: IPayload, callback: (response: Zone | null) => void): Promise<void> {
-    try {
-      if (!(await this.isCharacterGM())) return
-
-      this.logger.info(`User ${(await this.getCharacter())!.getId()} has requested zone via zone editor.`)
-
-      if (!data.zoneId) {
-        this.logger.info(`User ${(await this.getCharacter())!.getId()} tried to request zone but did not provide a zone id.`)
-        return callback(null)
-      }
-
-      const zone = await ZoneRepository.getById(data.zoneId)
-
-      if (!zone) {
-        this.logger.info(`User ${(await this.getCharacter())!.getId()} tried to request zone ${data.zoneId} but it does not exist.`)
-        return callback(null)
-      }
-
-      return callback(zone)
-    } catch (error: any) {
-      this.logger.error('gm:zone_editor:zone:request error', error.message)
-      return callback(null)
-    }
-  }
-}
diff --git a/src/events/gameMaster/zoneEditor/update.ts b/src/events/gameMaster/zoneEditor/update.ts
deleted file mode 100644
index 00dff01..0000000
--- a/src/events/gameMaster/zoneEditor/update.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import { BaseEvent } from '#application/base/baseEvent'
-import { ZoneEventTileType } from '#application/enums'
-import { UUID } from '#application/types'
-import { Zone } from '#entities/zone'
-import { ZoneEffect } from '#entities/zoneEffect'
-import { ZoneEventTile } from '#entities/zoneEventTile'
-import { ZoneEventTileTeleport } from '#entities/zoneEventTileTeleport'
-import { ZoneObject } from '#entities/zoneObject'
-import zoneManager from '#managers/zoneManager'
-import ZoneRepository from '#repositories/zoneRepository'
-
-interface IPayload {
-  zoneId: UUID
-  name: string
-  width: number
-  height: number
-  tiles: string[][]
-  pvp: boolean
-  zoneEventTiles: {
-    type: ZoneEventTileType
-    positionX: number
-    positionY: number
-    teleport?: {
-      toZoneId: UUID
-      toPositionX: number
-      toPositionY: number
-      toRotation: number
-    }
-  }[]
-  zoneEffects: {
-    effect: string
-    strength: number
-  }[]
-  zoneObjects: ZoneObject[]
-}
-
-export default class ZoneUpdateEvent extends BaseEvent {
-  public listen(): void {
-    this.socket.on('gm:zone_editor:zone:update', this.handleEvent.bind(this))
-  }
-
-  private async handleEvent(data: IPayload, callback: (response: Zone | null) => void): Promise<void> {
-    try {
-      if (!(await this.isCharacterGM())) return
-
-      const character = await this.getCharacter()
-      this.logger.info(`User ${character!.getId()} has updated zone via zone editor.`)
-
-      if (!data.zoneId) {
-        this.logger.info(`User ${character!.getId()} tried to update zone but did not provide a zone id.`)
-        return callback(null)
-      }
-
-      let zone = await ZoneRepository.getById(data.zoneId)
-
-      if (!zone) {
-        this.logger.info(`User ${character!.getId()} tried to update zone ${data.zoneId} but it does not exist.`)
-        return callback(null)
-      }
-
-      // Validation logic remains the same
-      if (data.tiles.length > data.height) {
-        data.tiles = data.tiles.slice(0, data.height)
-      }
-      for (let i = 0; i < data.tiles.length; i++) {
-        if (data.tiles[i].length > data.width) {
-          data.tiles[i] = data.tiles[i].slice(0, data.width)
-        }
-      }
-
-      data.zoneEventTiles = data.zoneEventTiles.filter((tile) => tile.positionX >= 0 && tile.positionX < data.width && tile.positionY >= 0 && tile.positionY < data.height)
-
-      data.zoneObjects = data.zoneObjects.filter((obj) => obj.positionX >= 0 && obj.positionX < data.width && obj.positionY >= 0 && obj.positionY < data.height)
-
-      // Clear existing collections
-      zone.zoneEventTiles.removeAll()
-      zone.zoneObjects.removeAll()
-      zone.zoneEffects.removeAll()
-
-      // Create and add new zone event tiles
-      for (const tile of data.zoneEventTiles) {
-        const zoneEventTile = new ZoneEventTile().setType(tile.type).setPositionX(tile.positionX).setPositionY(tile.positionY).setZone(zone)
-
-        if (tile.teleport) {
-          const teleport = new ZoneEventTileTeleport()
-            .setToZone((await ZoneRepository.getById(tile.teleport.toZoneId))!)
-            .setToPositionX(tile.teleport.toPositionX)
-            .setToPositionY(tile.teleport.toPositionY)
-            .setToRotation(tile.teleport.toRotation)
-
-          zoneEventTile.setTeleport(teleport)
-        }
-
-        zone.zoneEventTiles.add(zoneEventTile)
-      }
-
-      // Create and add new zone objects
-      for (const object of data.zoneObjects) {
-        const zoneObject = new ZoneObject().setMapObject(object.mapObject).setDepth(object.depth).setIsRotated(object.isRotated).setPositionX(object.positionX).setPositionY(object.positionY).setZone(zone)
-
-        zone.zoneObjects.add(zoneObject)
-      }
-
-      // Create and add new zone effects
-      for (const effect of data.zoneEffects) {
-        const zoneEffect = new ZoneEffect().setEffect(effect.effect).setStrength(effect.strength).setZone(zone)
-
-        zone.zoneEffects.add(zoneEffect)
-      }
-
-      // Update zone properties
-      await zone.setName(data.name).setWidth(data.width).setHeight(data.height).setTiles(data.tiles).setPvp(data.pvp).setUpdatedAt(new Date()).update()
-
-      // Reload zone from database to get fresh data
-      zone = await ZoneRepository.getById(data.zoneId)
-
-      if (!zone) {
-        this.logger.info(`User ${character!.getId()} tried to update zone ${data.zoneId} but it does not exist after update.`)
-        return callback(null)
-      }
-
-      // Reload zone for players
-      zoneManager.unloadZone(data.zoneId)
-      await zoneManager.loadZone(zone)
-
-      return callback(zone)
-    } catch (error: any) {
-      this.logger.error(`gm:zone_editor:zone:update error: ${error instanceof Error ? error.message : String(error)}`)
-      return callback(null)
-    }
-  }
-}
diff --git a/src/events/map/characterMove.ts b/src/events/map/characterMove.ts
new file mode 100644
index 0000000..5402bc4
--- /dev/null
+++ b/src/events/map/characterMove.ts
@@ -0,0 +1,104 @@
+import { BaseEvent } from '#application/base/baseEvent'
+import { MapEventTileWithTeleport } from '#application/types'
+import MapManager from '#managers/mapManager'
+import MapCharacter from '#models/mapCharacter'
+import mapEventTileRepository from '#repositories/mapEventTileRepository'
+import CharacterService from '#services/characterService'
+import MapEventTileService from '#services/mapEventTileService'
+
+export default class CharacterMove extends BaseEvent {
+  private readonly characterService = CharacterService
+  private readonly mapEventTileService = MapEventTileService
+
+  public listen(): void {
+    this.socket.on('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?.character) {
+      this.logger.error('map:character:move error: Character not found or not initialized')
+      return
+    }
+
+    // If already moving, cancel current movement and wait for it to fully stop
+    if (mapCharacter.isMoving) {
+      mapCharacter.isMoving = false
+      await new Promise((resolve) => setTimeout(resolve, 100))
+    }
+
+    const path = await this.characterService.calculatePath(mapCharacter.character, positionX, positionY)
+    if (!path) {
+      this.io.in(mapCharacter.character.map.id).emit('map:character:moveError', 'No valid path found')
+      return
+    }
+
+    // Start new movement
+    mapCharacter.isMoving = true
+    mapCharacter.currentPath = path // Add this property to MapCharacter class
+    await this.moveAlongPath(mapCharacter, path)
+  }
+
+  private async moveAlongPath(mapCharacter: MapCharacter, path: Array<{ x: number; y: number }>): Promise<void> {
+    const { character } = mapCharacter
+
+    for (let i = 0; i < path.length - 1; i++) {
+      if (!mapCharacter.isMoving || mapCharacter.currentPath !== path) {
+        return
+      }
+
+      const [start, end] = [path[i], path[i + 1]]
+      character.rotation = CharacterService.calculateRotation(start.x, start.y, end.x, end.y)
+
+      const mapEventTile = await mapEventTileRepository.getEventTileByMapIdAndPosition(character.map.id, Math.floor(end.x), Math.floor(end.y))
+
+      if (mapEventTile?.type === 'BLOCK') break
+      if (mapEventTile?.type === 'TELEPORT' && mapEventTile.teleport) {
+        await this.handleMapEventTile(mapEventTile as MapEventTileWithTeleport)
+        break
+      }
+
+      // Update position first
+      character.positionX = end.x
+      character.positionY = end.y
+
+      // Then emit with the same properties
+      this.io.in(character.map.id).emit('map:character:move', {
+        characterId: character.id,
+        positionX: character.positionX,
+        positionY: character.positionY,
+        rotation: character.rotation,
+        isMoving: true
+      })
+
+      await this.characterService.applyMovementDelay()
+    }
+
+    if (mapCharacter.isMoving && mapCharacter.currentPath === path) {
+      this.finalizeMovement(mapCharacter)
+    }
+  }
+
+  private async handleMapEventTile(mapEventTile: MapEventTileWithTeleport): Promise<void> {
+    const mapCharacter = MapManager.getCharacterById(this.socket.characterId!)
+    if (!mapCharacter) {
+      this.logger.error('map:character:move error: Character not found')
+      return
+    }
+
+    if (mapEventTile.teleport) {
+      await this.mapEventTileService.handleTeleport(this.io, this.socket, mapCharacter.character, mapEventTile.teleport)
+    }
+  }
+
+  private finalizeMovement(mapCharacter: MapCharacter): void {
+    mapCharacter.isMoving = false
+    this.io.in(mapCharacter.character.map.id).emit('map:character:move', {
+      characterId: mapCharacter.character.id,
+      positionX: mapCharacter.character.positionX,
+      positionY: mapCharacter.character.positionY,
+      rotation: mapCharacter.character.rotation,
+      isMoving: false
+    })
+  }
+}
diff --git a/src/events/zone/weather.ts b/src/events/map/weather.ts
similarity index 100%
rename from src/events/zone/weather.ts
rename to src/events/map/weather.ts
diff --git a/src/events/zone/characterMove.ts b/src/events/zone/characterMove.ts
deleted file mode 100644
index 406514d..0000000
--- a/src/events/zone/characterMove.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import { BaseEvent } from '#application/base/baseEvent'
-import { ZoneEventTileWithTeleport } from '#application/types'
-import ZoneManager from '#managers/zoneManager'
-import ZoneCharacter from '#models/zoneCharacter'
-import zoneEventTileRepository from '#repositories/zoneEventTileRepository'
-import CharacterService from '#services/characterService'
-import ZoneEventTileService from '#services/zoneEventTileService'
-
-export default class CharacterMove extends BaseEvent {
-  private readonly characterService = CharacterService
-  private readonly zoneEventTileService = ZoneEventTileService
-
-  public listen(): void {
-    this.socket.on('zone:character:move', this.handleEvent.bind(this))
-  }
-
-  private async handleEvent({ positionX, positionY }: { positionX: number; positionY: number }): Promise<void> {
-    const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
-    if (!zoneCharacter?.character) {
-      this.logger.error('zone:character:move error: Character not found or not initialized')
-      return
-    }
-
-    // If already moving, cancel current movement and wait for it to fully stop
-    if (zoneCharacter.isMoving) {
-      zoneCharacter.isMoving = false
-      await new Promise((resolve) => setTimeout(resolve, 100))
-    }
-
-    const path = await this.characterService.calculatePath(zoneCharacter.character, positionX, positionY)
-    if (!path) {
-      this.io.in(zoneCharacter.character.zone.id).emit('zone:character:moveError', 'No valid path found')
-      return
-    }
-
-    // Start new movement
-    zoneCharacter.isMoving = true
-    zoneCharacter.currentPath = path // Add this property to ZoneCharacter class
-    await this.moveAlongPath(zoneCharacter, path)
-  }
-
-  private async moveAlongPath(zoneCharacter: ZoneCharacter, path: Array<{ x: number; y: number }>): Promise<void> {
-    const { character } = zoneCharacter
-
-    for (let i = 0; i < path.length - 1; i++) {
-      if (!zoneCharacter.isMoving || zoneCharacter.currentPath !== path) {
-        return
-      }
-
-      const [start, end] = [path[i], path[i + 1]]
-      character.rotation = CharacterService.calculateRotation(start.x, start.y, end.x, end.y)
-
-      const zoneEventTile = await zoneEventTileRepository.getEventTileByZoneIdAndPosition(character.zone.id, Math.floor(end.x), Math.floor(end.y))
-
-      if (zoneEventTile?.type === 'BLOCK') break
-      if (zoneEventTile?.type === 'TELEPORT' && zoneEventTile.teleport) {
-        await this.handleZoneEventTile(zoneEventTile as ZoneEventTileWithTeleport)
-        break
-      }
-
-      // Update position first
-      character.positionX = end.x
-      character.positionY = end.y
-
-      // Then emit with the same properties
-      this.io.in(character.zone.id).emit('zone:character:move', {
-        characterId: character.id,
-        positionX: character.positionX,
-        positionY: character.positionY,
-        rotation: character.rotation,
-        isMoving: true
-      })
-
-      await this.characterService.applyMovementDelay()
-    }
-
-    if (zoneCharacter.isMoving && zoneCharacter.currentPath === path) {
-      this.finalizeMovement(zoneCharacter)
-    }
-  }
-
-  private async handleZoneEventTile(zoneEventTile: ZoneEventTileWithTeleport): Promise<void> {
-    const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
-    if (!zoneCharacter) {
-      this.logger.error('zone:character:move error: Character not found')
-      return
-    }
-
-    if (zoneEventTile.teleport) {
-      await this.zoneEventTileService.handleTeleport(this.io, this.socket, zoneCharacter.character, zoneEventTile.teleport)
-    }
-  }
-
-  private finalizeMovement(zoneCharacter: ZoneCharacter): void {
-    zoneCharacter.isMoving = false
-    this.io.in(zoneCharacter.character.zone.id).emit('zone:character:move', {
-      characterId: zoneCharacter.character.id,
-      positionX: zoneCharacter.character.positionX,
-      positionY: zoneCharacter.character.positionY,
-      rotation: zoneCharacter.character.rotation,
-      isMoving: false
-    })
-  }
-}
diff --git a/src/http/controllers/assets.ts b/src/http/controllers/assets.ts
index 758cb69..4be8bf9 100644
--- a/src/http/controllers/assets.ts
+++ b/src/http/controllers/assets.ts
@@ -8,7 +8,7 @@ import Storage from '#application/storage'
 import { AssetData, UUID } from '#application/types'
 import SpriteRepository from '#repositories/spriteRepository'
 import TileRepository from '#repositories/tileRepository'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapRepository from '#repositories/mapRepository'
 
 export class AssetsController extends BaseController {
   /**
@@ -28,24 +28,24 @@ export class AssetsController extends BaseController {
   }
 
   /**
-   * List tiles by zone
+   * List tiles by map
    * @param req
    * @param res
    */
-  public async listTilesByZone(req: Request, res: Response) {
-    const zoneId = req.params.zoneId as UUID
+  public async listTilesByMap(req: Request, res: Response) {
+    const mapId = req.params.mapId as UUID
 
-    if (!zoneId) {
-      return this.sendError(res, 'Invalid zone ID', 400)
+    if (!mapId) {
+      return this.sendError(res, 'Invalid map ID', 400)
     }
 
-    const zone = await ZoneRepository.getById(zoneId)
-    if (!zone) {
-      return this.sendError(res, 'Zone not found', 404)
+    const map = await MapRepository.getById(mapId)
+    if (!map) {
+      return this.sendError(res, 'Map not found', 404)
     }
 
     const assets: AssetData[] = []
-    const tiles = await TileRepository.getByZoneId(zoneId)
+    const tiles = await TileRepository.getByMapId(mapId)
 
     for (const tile of tiles) {
       assets.push({ key: tile.getId(), data: '/assets/tiles/' + tile.getId() + '.png', group: 'tiles', updatedAt: tile.getUpdatedAt() } as AssetData)
diff --git a/src/managers/httpManager.ts b/src/managers/httpManager.ts
index 957eab5..83e430a 100644
--- a/src/managers/httpManager.ts
+++ b/src/managers/httpManager.ts
@@ -33,7 +33,7 @@ class HttpManager {
 
     // Assets routes
     app.get('/assets/list_tiles', (req, res) => this.assetsController.listTiles(req, res))
-    app.get('/assets/list_tiles/:zoneId', (req, res) => this.assetsController.listTilesByZone(req, res))
+    app.get('/assets/list_tiles/:mapId', (req, res) => this.assetsController.listTilesByMap(req, res))
     app.get('/assets/list_sprite_actions/:spriteId', (req, res) => this.assetsController.listSpriteActions(req, res))
     app.get('/assets/:type/:spriteId?/:file', (req, res) => this.assetsController.downloadAsset(req, res))
   }
diff --git a/src/managers/mapManager.ts b/src/managers/mapManager.ts
new file mode 100644
index 0000000..cdb4cae
--- /dev/null
+++ b/src/managers/mapManager.ts
@@ -0,0 +1,50 @@
+import Logger, { LoggerType } from '#application/logger'
+import { UUID } from '#application/types'
+import { Map } from '#entities/map'
+import LoadedMap from '#models/loadedMap'
+import MapCharacter from '#models/mapCharacter'
+import MapRepository from '#repositories/mapRepository'
+
+class MapManager {
+  private readonly maps: Record<UUID, LoadedMap> = {}
+  private logger = Logger.type(LoggerType.GAME)
+
+  public async boot(): Promise<void> {
+    const maps = await MapRepository.getAll()
+    await Promise.all(maps.map((map) => this.loadMap(map)))
+
+    this.logger.info(`Map manager loaded with ${Object.keys(this.maps).length} maps`)
+  }
+
+  public async loadMap(map: Map): Promise<void> {
+    this.maps[map.id] = new LoadedMap(map)
+    this.logger.info(`Map ID ${map.id} loaded`)
+  }
+
+  public unloadMap(mapId: UUID): void {
+    delete this.maps[mapId]
+    this.logger.info(`Map ID ${mapId} unloaded`)
+  }
+
+  public getLoadedMaps(): LoadedMap[] {
+    return Object.values(this.maps)
+  }
+
+  public getMapById(mapId: UUID): LoadedMap | undefined {
+    return this.maps[mapId]
+  }
+
+  public getCharacterById(characterId: UUID): MapCharacter | undefined {
+    for (const map of Object.values(this.maps)) {
+      const character = map.getCharactersInMap().find((char) => char.character.id === characterId)
+      if (character) return character
+    }
+    return undefined
+  }
+
+  public removeCharacter(characterId: UUID): void {
+    Object.values(this.maps).forEach((map) => map.removeCharacter(characterId))
+  }
+}
+
+export default new MapManager()
\ No newline at end of file
diff --git a/src/managers/zoneManager.ts b/src/managers/zoneManager.ts
deleted file mode 100644
index 786fc0d..0000000
--- a/src/managers/zoneManager.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import Logger, { LoggerType } from '#application/logger'
-import { UUID } from '#application/types'
-import { Zone } from '#entities/zone'
-import LoadedZone from '#models/loadedZone'
-import ZoneCharacter from '#models/zoneCharacter'
-import ZoneRepository from '#repositories/zoneRepository'
-
-class ZoneManager {
-  private readonly zones = new Map<UUID, LoadedZone>()
-  private logger = Logger.type(LoggerType.GAME)
-
-  public async boot(): Promise<void> {
-    const zones = await ZoneRepository.getAll()
-    await Promise.all(zones.map((zone) => this.loadZone(zone)))
-
-    this.logger.info(`Zone manager loaded with ${this.zones.size} zones`)
-  }
-
-  public async loadZone(zone: Zone): Promise<void> {
-    const loadedZone = new LoadedZone(zone)
-    this.zones.set(zone.id, loadedZone)
-    this.logger.info(`Zone ID ${zone.id} loaded`)
-  }
-
-  public unloadZone(zoneId: UUID): void {
-    this.zones.delete(zoneId)
-    this.logger.info(`Zone ID ${zoneId} unloaded`)
-  }
-
-  public getLoadedZones(): LoadedZone[] {
-    return Array.from(this.zones.values())
-  }
-
-  public getZoneById(zoneId: UUID): LoadedZone | undefined {
-    return this.zones.get(zoneId)
-  }
-
-  public getCharacterById(characterId: UUID): ZoneCharacter | undefined {
-    for (const zone of this.zones.values()) {
-      const character = zone.getCharactersInZone().find((char) => char.character.id === characterId)
-      if (character) return character
-    }
-    return undefined
-  }
-
-  public removeCharacter(characterId: UUID): void {
-    this.zones.forEach((zone) => zone.removeCharacter(characterId))
-  }
-}
-
-export default new ZoneManager()
diff --git a/src/models/loadedMap.ts b/src/models/loadedMap.ts
new file mode 100644
index 0000000..ff65e67
--- /dev/null
+++ b/src/models/loadedMap.ts
@@ -0,0 +1,58 @@
+import MapCharacter from './mapCharacter'
+
+import { UUID } from '#application/types'
+import { Character } from '#entities/character'
+import { Map } from '#entities/map'
+import mapEventTileRepository from '#repositories/mapEventTileRepository'
+
+class LoadedMap {
+  private readonly map: Map
+  private characters: MapCharacter[] = []
+
+  constructor(map: Map) {
+    this.map = map
+  }
+
+  public getMap(): Map {
+    return this.map
+  }
+
+  public addCharacter(character: Character) {
+    const mapCharacter = new MapCharacter(character)
+    this.characters.push(mapCharacter)
+  }
+
+  public async removeCharacter(id: UUID) {
+    const mapCharacter = this.getCharacterById(id)
+    if (mapCharacter) {
+      await mapCharacter.savePosition()
+      this.characters = this.characters.filter((c) => c.character.id !== id)
+    }
+  }
+
+  public getCharacterById(id: UUID): MapCharacter | undefined {
+    return this.characters.find((c) => c.character.id === id)
+  }
+
+  public getCharactersInMap(): MapCharacter[] {
+    console.log(this.characters)
+    return this.characters
+  }
+
+  public async getGrid(): Promise<number[][]> {
+    let grid: number[][] = Array.from({ length: this.map.height }, () => Array.from({ length: this.map.width }, () => 0))
+
+    const eventTiles = await mapEventTileRepository.getAll(this.map.id)
+
+    // Set the grid values based on the event tiles, these are strings
+    eventTiles.forEach((eventTile) => {
+      if (eventTile.type === 'BLOCK') {
+        grid[eventTile.positionY][eventTile.positionX] = 1
+      }
+    })
+
+    return grid
+  }
+}
+
+export default LoadedMap
diff --git a/src/models/loadedZone.ts b/src/models/loadedZone.ts
deleted file mode 100644
index 92d54a9..0000000
--- a/src/models/loadedZone.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import ZoneCharacter from './zoneCharacter'
-
-import { UUID } from '#application/types'
-import { Character } from '#entities/character'
-import { Zone } from '#entities/zone'
-import zoneEventTileRepository from '#repositories/zoneEventTileRepository'
-
-class LoadedZone {
-  private readonly zone: Zone
-  private characters: ZoneCharacter[] = []
-
-  constructor(zone: Zone) {
-    this.zone = zone
-  }
-
-  public getZone(): Zone {
-    return this.zone
-  }
-
-  public addCharacter(character: Character) {
-    const zoneCharacter = new ZoneCharacter(character)
-    this.characters.push(zoneCharacter)
-  }
-
-  public async removeCharacter(id: UUID) {
-    const zoneCharacter = this.getCharacterById(id)
-    if (zoneCharacter) {
-      await zoneCharacter.savePosition()
-      this.characters = this.characters.filter((c) => c.character.id !== id)
-    }
-  }
-
-  public getCharacterById(id: UUID): ZoneCharacter | undefined {
-    return this.characters.find((c) => c.character.id === id)
-  }
-
-  public getCharactersInZone(): ZoneCharacter[] {
-    console.log(this.characters)
-    return this.characters
-  }
-
-  public async getGrid(): Promise<number[][]> {
-    let grid: number[][] = Array.from({ length: this.zone.height }, () => Array.from({ length: this.zone.width }, () => 0))
-
-    const eventTiles = await zoneEventTileRepository.getAll(this.zone.id)
-
-    // Set the grid values based on the event tiles, these are strings
-    eventTiles.forEach((eventTile) => {
-      if (eventTile.type === 'BLOCK') {
-        grid[eventTile.positionY][eventTile.positionX] = 1
-      }
-    })
-
-    return grid
-  }
-}
-
-export default LoadedZone
diff --git a/src/models/zoneCharacter.ts b/src/models/mapCharacter.ts
similarity index 67%
rename from src/models/zoneCharacter.ts
rename to src/models/mapCharacter.ts
index 008d835..3fc2aa2 100644
--- a/src/models/zoneCharacter.ts
+++ b/src/models/mapCharacter.ts
@@ -3,10 +3,10 @@ import { Server } from 'socket.io'
 import { TSocket } from '#application/types'
 import { Character } from '#entities/character'
 import SocketManager from '#managers/socketManager'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 import TeleportService from '#services/teleportService'
 
-class ZoneCharacter {
+class MapCharacter {
   public readonly character: Character
   public isMoving: boolean = false
   public currentPath: Array<{ x: number; y: number }> | null = null
@@ -16,12 +16,12 @@ class ZoneCharacter {
   }
 
   public async savePosition() {
-    await this.character.setPositionX(this.character.positionX).setPositionY(this.character.positionY).setRotation(this.character.rotation).setZone(this.character.zone).update()
+    await this.character.setPositionX(this.character.positionX).setPositionY(this.character.positionY).setRotation(this.character.rotation).setMap(this.character.map).update()
   }
 
-  public async teleport(zoneId: number, targetX: number, targetY: number): Promise<void> {
+  public async teleport(mapId: number, targetX: number, targetY: number): Promise<void> {
     await TeleportService.teleportCharacter(this.character.id, {
-      targetZoneId: zoneId,
+      targetMapId: mapId,
       targetX,
       targetY
     })
@@ -34,13 +34,13 @@ class ZoneCharacter {
       this.currentPath = null
       await this.savePosition()
 
-      // Leave zone and remove from manager
-      if (this.character.zone) {
-        socket.leave(this.character.zone.id)
-        ZoneManager.removeCharacter(this.character.id)
+      // Leave map and remove from manager
+      if (this.character.map) {
+        socket.leave(this.character.map.id)
+        MapManager.removeCharacter(this.character.id)
 
-        // Notify zone players
-        io.in(this.character.zone.id).emit('zone:character:leave', this.character.id)
+        // Notify map players
+        io.in(this.character.map.id).emit('map:character:leave', this.character.id)
       }
 
       // Notify all players
@@ -51,4 +51,4 @@ class ZoneCharacter {
   }
 }
 
-export default ZoneCharacter
+export default MapCharacter
diff --git a/src/repositories/chatRepository.ts b/src/repositories/chatRepository.ts
index a4495b3..e6807c2 100644
--- a/src/repositories/chatRepository.ts
+++ b/src/repositories/chatRepository.ts
@@ -35,12 +35,12 @@ class ChatRepository extends BaseRepository {
     }
   }
 
-  async getByZoneId(zoneId: UUID): Promise<Chat[]> {
+  async getByMapId(mapId: UUID): Promise<Chat[]> {
     try {
       const repository = this.em.getRepository(Chat)
-      return await repository.find({ zone: zoneId })
+      return await repository.find({ map: mapId })
     } catch (error: any) {
-      this.logger.error(`Failed to get chats by zone ID: ${error instanceof Error ? error.message : String(error)}`)
+      this.logger.error(`Failed to get chats by map ID: ${error instanceof Error ? error.message : String(error)}`)
       return []
     }
   }
diff --git a/src/repositories/mapEventTileRepository.ts b/src/repositories/mapEventTileRepository.ts
new file mode 100644
index 0000000..6e2473a
--- /dev/null
+++ b/src/repositories/mapEventTileRepository.ts
@@ -0,0 +1,33 @@
+import { BaseRepository } from '#application/base/baseRepository'
+import { UUID } from '#application/types'
+import { MapEventTile } from '#entities/mapEventTile'
+
+class MapEventTileRepository extends BaseRepository {
+  async getAll(id: UUID): Promise<MapEventTile[]> {
+    try {
+      const repository = this.em.getRepository(MapEventTile)
+      return await repository.find({
+        map: id
+      })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map event tiles: ${error.message}`)
+      return []
+    }
+  }
+
+  async getEventTileByMapIdAndPosition(mapId: UUID, positionX: number, positionY: number) {
+    try {
+      const repository = this.em.getRepository(MapEventTile)
+      return await repository.findOne({
+        map: mapId,
+        positionX: positionX,
+        positionY: positionY
+      })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map event tile: ${error.message}`)
+      return null
+    }
+  }
+}
+
+export default new MapEventTileRepository()
diff --git a/src/repositories/mapRepository.ts b/src/repositories/mapRepository.ts
new file mode 100644
index 0000000..7708ed3
--- /dev/null
+++ b/src/repositories/mapRepository.ts
@@ -0,0 +1,73 @@
+import { BaseRepository } from '#application/base/baseRepository'
+import { UUID } from '#application/types'
+import { Map } from '#entities/map'
+import { MapEventTile } from '#entities/mapEventTile'
+import { MapObject } from '#entities/mapObject'
+
+class MapRepository extends BaseRepository {
+  async getFirst(): Promise<Map | null> {
+    try {
+      const repository = this.em.getRepository(Map)
+      return await repository.findOne({ id: { $exists: true } })
+    } catch (error: any) {
+      this.logger.error(`Failed to get first map: ${error instanceof Error ? error.message : String(error)}`)
+      return null
+    }
+  }
+
+  async getAll(): Promise<Map[]> {
+    try {
+      const repository = this.em.getRepository(Map)
+      return await repository.findAll()
+    } catch (error: any) {
+      this.logger.error(`Failed to get all map: ${error.message}`)
+      return []
+    }
+  }
+
+  async getById(id: UUID) {
+    try {
+      const repository = this.em.getRepository(Map)
+      return await repository.findOne({ id })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map by id: ${error.message}`)
+      return null
+    }
+  }
+
+  async getEventTiles(id: UUID): Promise<MapEventTile[]> {
+    try {
+      const repository = this.em.getRepository(MapEventTile)
+      return await repository.find({ map: id })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map event tiles: ${error.message}`)
+      return []
+    }
+  }
+
+  async getFirstEventTile(mapId: UUID, positionX: number, positionY: number): Promise<MapEventTile | null> {
+    try {
+      const repository = this.em.getRepository(MapEventTile)
+      return await repository.findOne({
+        map: mapId,
+        positionX: positionX,
+        positionY: positionY
+      })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map event tile: ${error.message}`)
+      return null
+    }
+  }
+
+  async getMapObjects(id: UUID): Promise<MapObject[]> {
+    try {
+      const repository = this.em.getRepository(MapObject)
+      return await repository.find({ map: id })
+    } catch (error: any) {
+      this.logger.error(`Failed to get map objects: ${error.message}`)
+      return []
+    }
+  }
+}
+
+export default new MapRepository()
diff --git a/src/repositories/tileRepository.ts b/src/repositories/tileRepository.ts
index b61eb75..172a755 100644
--- a/src/repositories/tileRepository.ts
+++ b/src/repositories/tileRepository.ts
@@ -4,8 +4,8 @@ import { BaseRepository } from '#application/base/baseRepository'
 import { UUID } from '#application/types'
 import { unduplicateArray } from '#application/utilities'
 import { Tile } from '#entities/tile'
-import { Zone } from '#entities/zone'
-import ZoneService from '#services/zoneService'
+import { Map } from '#entities/map'
+import MapService from '#services/mapService'
 
 class TileRepository extends BaseRepository {
   async getById(id: UUID) {
@@ -37,18 +37,18 @@ class TileRepository extends BaseRepository {
     }
   }
 
-  async getByZoneId(zoneId: UUID) {
+  async getByMapId(mapId: UUID) {
     try {
-      const repository = this.em.getRepository(Zone)
+      const repository = this.em.getRepository(Map)
       const tileRepository = this.em.getRepository(Tile)
 
-      const zone = await repository.findOne({ id: zoneId })
-      if (!zone) return []
+      const map = await repository.findOne({ id: mapId })
+      if (!map) return []
 
-      const zoneTileArray = unduplicateArray(ZoneService.flattenZoneArray(JSON.parse(JSON.stringify(zone.tiles))))
+      const mapTileArray = unduplicateArray(MapService.flattenMapArray(JSON.parse(JSON.stringify(map.tiles))))
 
       return await tileRepository.find({
-        id: zoneTileArray
+        id: mapTileArray
       })
     } catch (error: any) {
       return []
diff --git a/src/repositories/zoneEventTileRepository.ts b/src/repositories/zoneEventTileRepository.ts
deleted file mode 100644
index 1560d8c..0000000
--- a/src/repositories/zoneEventTileRepository.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { BaseRepository } from '#application/base/baseRepository'
-import { UUID } from '#application/types'
-import { ZoneEventTile } from '#entities/zoneEventTile'
-
-class ZoneEventTileRepository extends BaseRepository {
-  async getAll(id: UUID): Promise<ZoneEventTile[]> {
-    try {
-      const repository = this.em.getRepository(ZoneEventTile)
-      return await repository.find({
-        zone: id
-      })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone event tiles: ${error.message}`)
-      return []
-    }
-  }
-
-  async getEventTileByZoneIdAndPosition(zoneId: UUID, positionX: number, positionY: number) {
-    try {
-      const repository = this.em.getRepository(ZoneEventTile)
-      return await repository.findOne({
-        zone: zoneId,
-        positionX: positionX,
-        positionY: positionY
-      })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone event tile: ${error.message}`)
-      return null
-    }
-  }
-}
-
-export default new ZoneEventTileRepository()
diff --git a/src/repositories/zoneRepository.ts b/src/repositories/zoneRepository.ts
deleted file mode 100644
index e0e9af6..0000000
--- a/src/repositories/zoneRepository.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { BaseRepository } from '#application/base/baseRepository'
-import { UUID } from '#application/types'
-import { Zone } from '#entities/zone'
-import { ZoneEventTile } from '#entities/zoneEventTile'
-import { ZoneObject } from '#entities/zoneObject'
-
-class ZoneRepository extends BaseRepository {
-  async getFirst(): Promise<Zone | null> {
-    try {
-      const repository = this.em.getRepository(Zone)
-      return await repository.findOne({ id: { $exists: true } })
-    } catch (error: any) {
-      this.logger.error(`Failed to get first zone: ${error instanceof Error ? error.message : String(error)}`)
-      return null
-    }
-  }
-
-  async getAll(): Promise<Zone[]> {
-    try {
-      const repository = this.em.getRepository(Zone)
-      return await repository.findAll()
-    } catch (error: any) {
-      this.logger.error(`Failed to get all zone: ${error.message}`)
-      return []
-    }
-  }
-
-  async getById(id: UUID) {
-    try {
-      const repository = this.em.getRepository(Zone)
-      return await repository.findOne({ id })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone by id: ${error.message}`)
-      return null
-    }
-  }
-
-  async getEventTiles(id: UUID): Promise<ZoneEventTile[]> {
-    try {
-      const repository = this.em.getRepository(ZoneEventTile)
-      return await repository.find({ zone: id })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone event tiles: ${error.message}`)
-      return []
-    }
-  }
-
-  async getFirstEventTile(zoneId: UUID, positionX: number, positionY: number): Promise<ZoneEventTile | null> {
-    try {
-      const repository = this.em.getRepository(ZoneEventTile)
-      return await repository.findOne({
-        zone: zoneId,
-        positionX: positionX,
-        positionY: positionY
-      })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone event tile: ${error.message}`)
-      return null
-    }
-  }
-
-  async getZoneObjects(id: UUID): Promise<ZoneObject[]> {
-    try {
-      const repository = this.em.getRepository(ZoneObject)
-      return await repository.find({ zone: id })
-    } catch (error: any) {
-      this.logger.error(`Failed to get zone objects: ${error.message}`)
-      return []
-    }
-  }
-}
-
-export default new ZoneRepository()
diff --git a/src/server.ts b/src/server.ts
index c747ec2..71f0a80 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -13,7 +13,7 @@ import QueueManager from '#managers/queueManager'
 import SocketManager from '#managers/socketManager'
 import UserManager from '#managers/userManager'
 import WeatherManager from '#managers/weatherManager'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 
 export class Server {
   private readonly app: Application
@@ -45,7 +45,7 @@ export class Server {
         UserManager.boot(),
         // DateManager.boot(),
         // WeatherManager.boot(),
-        ZoneManager.boot(),
+        MapManager.boot(),
         ConsoleManager.boot()
       ])
     } catch (error: any) {
diff --git a/src/services/characterService.ts b/src/services/characterService.ts
index 5ec478a..188d211 100644
--- a/src/services/characterService.ts
+++ b/src/services/characterService.ts
@@ -1,11 +1,11 @@
 import { BaseService } from '#application/base/baseService'
 import config from '#application/config'
 import { Character } from '#entities/character'
-import { Zone } from '#entities/zone'
+import { Map } from '#entities/map'
 import SocketManager from '#managers/socketManager'
-import ZoneManager from '#managers/zoneManager'
+import MapManager from '#managers/mapManager'
 import CharacterRepository from '#repositories/characterRepository'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapRepository from '#repositories/mapRepository'
 
 type Position = { x: number; y: number }
 export type Node = Position & { parent?: Node; g: number; h: number; f: number }
@@ -24,11 +24,11 @@ class CharacterService extends BaseService {
   ]
 
   public async calculatePath(character: Character, targetX: number, targetY: number): Promise<Position[] | null> {
-    const zone = ZoneManager.getZoneById(character.zone.id)
-    const grid = await zone?.getGrid()
+    const map = MapManager.getMapById(character.map.id)
+    const grid = await map?.getGrid()
 
     if (!grid?.length) {
-      this.logger.error('zone:character:move error: Grid not found or empty')
+      this.logger.error('map:character:move error: Grid not found or empty')
       return null
     }
 
diff --git a/src/services/chatService.ts b/src/services/chatService.ts
index d29948d..4122a16 100644
--- a/src/services/chatService.ts
+++ b/src/services/chatService.ts
@@ -6,22 +6,22 @@ import { Chat } from '#entities/chat'
 import SocketManager from '#managers/socketManager'
 import CharacterRepository from '#repositories/characterRepository'
 import ChatRepository from '#repositories/chatRepository'
-import ZoneRepository from '#repositories/zoneRepository'
+import MapRepository from '#repositories/mapRepository'
 
 class ChatService extends BaseService {
-  async sendZoneMessage(characterId: UUID, zoneId: UUID, message: string): Promise<boolean> {
+  async sendMapMessage(characterId: UUID, mapId: UUID, message: string): Promise<boolean> {
     try {
       const character = await CharacterRepository.getById(characterId)
       if (!character) return false
 
-      const zone = await ZoneRepository.getById(zoneId)
-      if (!zone) return false
+      const map = await MapRepository.getById(mapId)
+      if (!map) return false
 
       const chat = new Chat()
-      await chat.setCharacter(character).setZone(zone).setMessage(message).save()
+      await chat.setCharacter(character).setMap(map).setMessage(message).save()
 
       const io = SocketManager.getIO()
-      io.to(zoneId).emit('chat:message', chat)
+      io.to(mapId).emit('chat:message', chat)
       return true
     } catch (error: any) {
       this.logger.error(`Failed to save chat message: ${error instanceof Error ? error.message : String(error)}`)
diff --git a/src/services/mapEventTileService.ts b/src/services/mapEventTileService.ts
new file mode 100644
index 0000000..06b45ac
--- /dev/null
+++ b/src/services/mapEventTileService.ts
@@ -0,0 +1,49 @@
+import { Server } from 'socket.io'
+
+import { BaseService } from '#application/base/baseService'
+import { ExtendedCharacter, TSocket } from '#application/types'
+import { MapEventTileTeleport } from '#entities/mapEventTileTeleport'
+import MapManager from '#managers/mapManager'
+
+class MapEventTileService extends BaseService {
+  public async handleTeleport(io: Server, socket: TSocket, character: ExtendedCharacter, teleport: MapEventTileTeleport): Promise<void> {
+    if (teleport.toMap.id === character.map.id) return
+
+    const loadedMap = MapManager.getMapById(teleport.toMap.id)
+    if (!loadedMap) {
+      this.logger.error('map:character:join error: Loaded map not found')
+      return
+    }
+
+    const map = loadedMap.getMap()
+
+    const oldMapId = character.map.id
+    const newMapId = teleport.toMap.id
+
+    character.isMoving = false
+    // Update local character object
+    character.setMap(teleport.toMap).setRotation(teleport.toRotation).setPositionX(teleport.toPositionX).setPositionY(teleport.toPositionY)
+
+    await character.save()
+
+    // Remove and add character to new map
+    await loadedMap.removeCharacter(character.id)
+    loadedMap.addCharacter(character)
+
+    // Emit events
+    io.to(oldMapId).emit('map:character:leave', character.id)
+    io.to(newMapId).emit('map:character:join', character)
+
+    // Update socket rooms
+    socket.leave(oldMapId)
+    socket.join(newMapId)
+
+    // Send teleport information to the client
+    socket.emit('map:character:teleport', {
+      map,
+      characters: loadedMap.getCharactersInMap()
+    })
+  }
+}
+
+export default new MapEventTileService()
diff --git a/src/services/zoneService.ts b/src/services/mapService.ts
similarity index 61%
rename from src/services/zoneService.ts
rename to src/services/mapService.ts
index d658017..ed0d17e 100644
--- a/src/services/zoneService.ts
+++ b/src/services/mapService.ts
@@ -1,7 +1,7 @@
 import { BaseService } from '#application/base/baseService'
 
-class ZoneService extends BaseService {
-  public flattenZoneArray(tiles: string[][]) {
+class MapService extends BaseService {
+  public flattenMapArray(tiles: string[][]) {
     const normalArray = []
 
     for (const row of tiles) {
@@ -12,4 +12,4 @@ class ZoneService extends BaseService {
   }
 }
 
-export default new ZoneService()
+export default new MapService()
diff --git a/src/services/teleportService.ts b/src/services/teleportService.ts
index 0c86414..8f4e436 100644
--- a/src/services/teleportService.ts
+++ b/src/services/teleportService.ts
@@ -2,11 +2,11 @@ import Logger, { LoggerType } from '#application/logger'
 import { UUID } from '#application/types'
 import { Character } from '#entities/character'
 import SocketManager from '#managers/socketManager'
-import ZoneManager from '#managers/zoneManager'
-import ZoneCharacter from '#models/zoneCharacter'
+import MapManager from '#managers/mapManager'
+import MapCharacter from '#models/mapCharacter'
 
 interface TeleportOptions {
-  targetZoneId: UUID
+  targetMapId: UUID
   targetX: number
   targetY: number
   rotation?: number
@@ -18,13 +18,13 @@ class TeleportService {
   private readonly logger = Logger.type(LoggerType.GAME)
 
   public async teleportCharacter(characterId: UUID, options: TeleportOptions): Promise<boolean> {
-    const { targetZoneId, targetX, targetY, rotation = 0, isInitialJoin = false, character } = options
+    const { targetMapId, targetX, targetY, rotation = 0, isInitialJoin = false, character } = options
 
     const socket = SocketManager.getSocketByCharacterId(characterId)
-    const targetZone = ZoneManager.getZoneById(targetZoneId)
+    const targetMap = MapManager.getMapById(targetMapId)
 
-    if (!socket || !targetZone) {
-      this.logger.error(`Teleport failed - Missing socket or target zone for character ${characterId}`)
+    if (!socket || !targetMap) {
+      this.logger.error(`Teleport failed - Missing socket or target map for character ${characterId}`)
       return false
     }
 
@@ -33,40 +33,40 @@ class TeleportService {
       return false
     }
 
-    const existingCharacter = !isInitialJoin && ZoneManager.getCharacterById(characterId)
-    const zoneCharacter = isInitialJoin
-      ? new ZoneCharacter(character!)
+    const existingCharacter = !isInitialJoin && MapManager.getCharacterById(characterId)
+    const mapCharacter = isInitialJoin
+      ? new MapCharacter(character!)
       : existingCharacter ||
         (() => {
-          this.logger.error(`Teleport failed - Character ${characterId} not found in ZoneManager`)
+          this.logger.error(`Teleport failed - Character ${characterId} not found in MapManager`)
           return null
         })()
 
-    if (!zoneCharacter) return false
+    if (!mapCharacter) return false
 
     try {
-      const currentZoneId = zoneCharacter.character.zone?.id
+      const currentMapId = mapCharacter.character.map?.id
       const io = SocketManager.getIO()
 
-      // Handle current zone cleanup
-      if (currentZoneId) {
-        socket.leave(currentZoneId)
-        ZoneManager.removeCharacter(characterId)
-        io.in(currentZoneId).emit('zone:character:leave', characterId)
+      // Handle current map cleanup
+      if (currentMapId) {
+        socket.leave(currentMapId)
+        MapManager.removeCharacter(characterId)
+        io.in(currentMapId).emit('map:character:leave', characterId)
       }
 
-      // Update character position and zone
-      await zoneCharacter.character.setPositionX(targetX).setPositionY(targetY).setRotation(rotation).setZone(targetZone.getZone()).update()
+      // Update character position and map
+      await mapCharacter.character.setPositionX(targetX).setPositionY(targetY).setRotation(rotation).setMap(targetMap.getMap()).update()
 
-      // Join new zone
-      socket.join(targetZoneId)
-      targetZone.addCharacter(zoneCharacter.character)
+      // Join new map
+      socket.join(targetMapId)
+      targetMap.addCharacter(mapCharacter.character)
 
       // Notify clients
-      io.in(targetZoneId).emit('zone:character:join', zoneCharacter)
-      socket.emit('zone:character:teleport', {
-        zone: targetZone.getZone(),
-        characters: targetZone.getCharactersInZone()
+      io.in(targetMapId).emit('map:character:join', mapCharacter)
+      socket.emit('map:character:teleport', {
+        map: targetMap.getMap(),
+        characters: targetMap.getCharactersInMap()
       })
 
       return true
diff --git a/src/services/zoneEventTileService.ts b/src/services/zoneEventTileService.ts
deleted file mode 100644
index 66fe3a2..0000000
--- a/src/services/zoneEventTileService.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Server } from 'socket.io'
-
-import { BaseService } from '#application/base/baseService'
-import { ExtendedCharacter, TSocket } from '#application/types'
-import { ZoneEventTileTeleport } from '#entities/zoneEventTileTeleport'
-import ZoneManager from '#managers/zoneManager'
-
-class ZoneEventTileService extends BaseService {
-  public async handleTeleport(io: Server, socket: TSocket, character: ExtendedCharacter, teleport: ZoneEventTileTeleport): Promise<void> {
-    if (teleport.toZone.id === character.zone.id) return
-
-    const loadedZone = ZoneManager.getZoneById(teleport.toZone.id)
-    if (!loadedZone) {
-      this.logger.error('zone:character:join error: Loaded zone not found')
-      return
-    }
-
-    const zone = loadedZone.getZone()
-
-    const oldZoneId = character.zone.id
-    const newZoneId = teleport.toZone.id
-
-    character.isMoving = false
-    // Update local character object
-    character.setZone(teleport.toZone).setRotation(teleport.toRotation).setPositionX(teleport.toPositionX).setPositionY(teleport.toPositionY)
-
-    await character.save()
-
-    // Remove and add character to new zone
-    await loadedZone.removeCharacter(character.id)
-    loadedZone.addCharacter(character)
-
-    // Emit events
-    io.to(oldZoneId).emit('zone:character:leave', character.id)
-    io.to(newZoneId).emit('zone:character:join', character)
-
-    // Update socket rooms
-    socket.leave(oldZoneId)
-    socket.join(newZoneId)
-
-    // Send teleport information to the client
-    socket.emit('zone:character:teleport', {
-      zone,
-      characters: loadedZone.getCharactersInZone()
-    })
-  }
-}
-
-export default new ZoneEventTileService()