diff --git a/.gitignore b/.gitignore
index 8f6d3e2..eeac31a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -309,7 +309,4 @@ $RECYCLE.BIN/
 # Windows shortcuts
 *.lnk
 
-# End of https://www.toptal.com/developers/gitignore/api/node,jetbrains+all,visualstudiocode,macos,windows
-
-prisma/dev.db
-prisma/dev.db-journal
\ No newline at end of file
+# End of https://www.toptal.com/developers/gitignore/api/node,jetbrains+all,visualstudiocode,macos,windows
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c173541..08412ba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,9 +44,9 @@
       }
     },
     "node_modules/@emnapi/runtime": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.0.tgz",
-      "integrity": "sha512-XMBySMuNZs3DM96xcJmLW4EfGnf+uGmFNjzpehMjuX5PLB5j87ar2Zc4e3PVeZ3I5g3tYtAqskB28manlF69Zw==",
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+      "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
       "license": "MIT",
       "optional": true,
       "dependencies": {
@@ -719,9 +719,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.16.10",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz",
-      "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==",
+      "version": "20.16.11",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz",
+      "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==",
       "license": "MIT",
       "dependencies": {
         "undici-types": "~6.19.2"
@@ -982,9 +982,9 @@
       "license": "BSD-3-Clause"
     },
     "node_modules/bullmq": {
-      "version": "5.15.0",
-      "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.15.0.tgz",
-      "integrity": "sha512-h53shVjx8s6wxYGtUfzAfENpSP7N5T0D4PMTvbZncozLjb8yUKhopfpa7PmcpQfq7SSO9dm/OZ9XQuGOCSGNug==",
+      "version": "5.20.0",
+      "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.20.0.tgz",
+      "integrity": "sha512-eCJyYJqNUl9swC39x2fVm1BUv5BuO/nv2eAcAsz58znue0ZCYgSG+yWXZeauRG98Jl0UIBcPgJtbF+c9Wd+Odg==",
       "license": "MIT",
       "dependencies": {
         "cron-parser": "^4.6.0",
@@ -1128,9 +1128,9 @@
       }
     },
     "node_modules/cookie": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
-      "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+      "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
       "license": "MIT",
       "engines": {
         "node": ">= 0.6"
@@ -1282,9 +1282,9 @@
       }
     },
     "node_modules/engine.io": {
-      "version": "6.6.1",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz",
-      "integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==",
+      "version": "6.6.2",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz",
+      "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==",
       "license": "MIT",
       "dependencies": {
         "@types/cookie": "^0.4.1",
@@ -1292,7 +1292,7 @@
         "@types/node": ">=10.0.0",
         "accepts": "~1.3.4",
         "base64id": "2.0.0",
-        "cookie": "~0.4.1",
+        "cookie": "~0.7.2",
         "cors": "~2.8.5",
         "debug": "~4.3.1",
         "engine.io-parser": "~5.2.1",
@@ -1312,9 +1312,9 @@
       }
     },
     "node_modules/engine.io/node_modules/cookie": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
-      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+      "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
       "license": "MIT",
       "engines": {
         "node": ">= 0.6"
@@ -1398,9 +1398,9 @@
       }
     },
     "node_modules/express": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
-      "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
+      "version": "4.21.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
+      "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
       "license": "MIT",
       "dependencies": {
         "accepts": "~1.3.8",
@@ -1408,7 +1408,7 @@
         "body-parser": "1.20.3",
         "content-disposition": "0.5.4",
         "content-type": "~1.0.4",
-        "cookie": "0.6.0",
+        "cookie": "0.7.1",
         "cookie-signature": "1.0.6",
         "debug": "2.6.9",
         "depd": "2.0.0",
@@ -2867,9 +2867,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.6.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
-      "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
+      "version": "5.6.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
+      "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
       "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
diff --git a/prisma/schema/zone.prisma b/prisma/schema/zone.prisma
index f980b0a..3772e1c 100644
--- a/prisma/schema/zone.prisma
+++ b/prisma/schema/zone.prisma
@@ -38,6 +38,7 @@ model Zone {
   height                 Int                     @default(10)
   tiles                  Json?
   pvp                    Boolean                 @default(false)
+  effects                ZoneEffect[]
   zoneEventTiles         ZoneEventTile[]
   zoneEventTileTeleports ZoneEventTileTeleport[]
   zoneObjects            ZoneObject[]
@@ -47,6 +48,14 @@ model Zone {
   updatedAt              DateTime                @updatedAt
 }
 
+model ZoneEffect {
+  id       String @id @default(uuid())
+  zoneId   Int
+  zone     Zone   @relation(fields: [zoneId], references: [id], onDelete: Cascade)
+  effect   String
+  strength Int
+}
+
 model ZoneObject {
   id        String  @id @default(uuid())
   zoneId    Int
diff --git a/src/commands/tiles.ts b/src/commands/tiles.ts
index 0a59de9..02f2d39 100644
--- a/src/commands/tiles.ts
+++ b/src/commands/tiles.ts
@@ -2,7 +2,7 @@ import fs from 'fs'
 import sharp from 'sharp'
 import { commandLogger } from '../utilities/logger'
 import { Server } from 'socket.io'
-import { getPublicPath } from '../utilities/utilities'
+import { getPublicPath } from '../utilities/files'
 import path from 'path'
 
 export default class TilesCommand {
diff --git a/src/managers/commandManager.ts b/src/managers/commandManager.ts
index e56d194..4c8a1a0 100644
--- a/src/managers/commandManager.ts
+++ b/src/managers/commandManager.ts
@@ -3,7 +3,7 @@ import * as fs from 'fs'
 import * as path from 'path'
 import { Server } from 'socket.io'
 import { commandLogger } from '../utilities/logger'
-import { getAppPath } from '../utilities/utilities'
+import { getAppPath } from '../utilities/files'
 
 class CommandManager {
   private commands: Map<string, any> = new Map()
diff --git a/src/managers/datetimeManager.ts b/src/managers/datetimeManager.ts
new file mode 100644
index 0000000..7dc2c0e
--- /dev/null
+++ b/src/managers/datetimeManager.ts
@@ -0,0 +1,84 @@
+// src/managers/datetimeManager.ts
+
+import fs from 'fs/promises'
+import { Server } from 'socket.io'
+import { appLogger } from '../utilities/logger'
+import { createDir, doesPathExist, getRootPath } from '../utilities/files'
+
+class DatetimeManager {
+  private static readonly GAME_SPEED = 24 / 3 // 24 hours / 3 hours = 8x speed
+  private static readonly UPDATE_INTERVAL = 1000 // Update every second for smooth second transitions
+
+  private io: Server | null = null
+  private intervalId: NodeJS.Timeout | null = null
+
+  public async boot(io: Server): Promise<void> {
+    this.io = io
+    this.startDateTimeLoop()
+    appLogger.info('Datetime manager loaded')
+  }
+
+  public stop(): void {
+    if (this.intervalId) {
+      clearInterval(this.intervalId)
+      this.intervalId = null
+    }
+  }
+
+  public async loadDateTime(): Promise<Date> {
+    try {
+      const datetimeFilePath = this.getDatetimeFilePath()
+      const content = await fs.readFile(datetimeFilePath, 'utf-8')
+      return new Date(content.trim())
+    } catch (error) {
+      appLogger.error(`Failed to load datetime: ${error instanceof Error ? error.message : String(error)}`)
+      return new Date() // Use current date as fallback
+    }
+  }
+
+  private startDateTimeLoop(): void {
+    this.intervalId = setInterval(async () => {
+      const currentDateTime = await this.loadDateTime()
+      this.advanceGameTime(currentDateTime)
+      this.emitDateTime(currentDateTime)
+      this.saveDateTimeIfNeeded(currentDateTime)
+    }, DatetimeManager.UPDATE_INTERVAL)
+  }
+
+  private advanceGameTime(currentDateTime: Date): void {
+    const advanceTime = (DatetimeManager.GAME_SPEED * DatetimeManager.UPDATE_INTERVAL) / 1000 * 1000
+    currentDateTime.setTime(currentDateTime.getTime() + advanceTime)
+  }
+
+  private emitDateTime(currentDateTime: Date): void {
+    this.io?.emit('datetime', this.formatDateTime(currentDateTime))
+  }
+
+  private formatDateTime(date: Date): string {
+    return date.toISOString().slice(0, 19).replace('T', ' ')
+  }
+
+  private saveDateTimeIfNeeded(currentDateTime: Date): void {
+    if (currentDateTime.getMilliseconds() < DatetimeManager.UPDATE_INTERVAL) {
+      this.saveDateTime(currentDateTime)
+    }
+  }
+
+  private async saveDateTime(currentDateTime: Date): Promise<void> {
+    try {
+      const datetimeFilePath = this.getDatetimeFilePath()
+      await fs.writeFile(datetimeFilePath, this.formatDateTime(currentDateTime))
+    } catch (error) {
+      appLogger.error(`Failed to save datetime: ${error instanceof Error ? error.message : String(error)}`)
+    }
+  }
+
+  private getDatetimeFilePath(): string {
+    if (!doesPathExist(getRootPath('data'))) {
+      createDir(getRootPath('data'))
+    }
+    return getRootPath('data', 'datetime.txt')
+  }
+}
+
+export default new DatetimeManager()
\ No newline at end of file
diff --git a/src/managers/queueManager.ts b/src/managers/queueManager.ts
index 9856619..d05fe7d 100644
--- a/src/managers/queueManager.ts
+++ b/src/managers/queueManager.ts
@@ -5,7 +5,7 @@ import { Server as SocketServer } from 'socket.io'
 import { TSocket } from '../utilities/types'
 import { queueLogger } from '../utilities/logger'
 import fs from 'fs'
-import { getAppPath } from '../utilities/utilities'
+import { getAppPath } from '../utilities/files'
 
 class QueueManager {
   private connection!: IORedis
diff --git a/src/managers/weatherManager.ts b/src/managers/weatherManager.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/server.ts b/src/server.ts
index 959bc7e..d9b1bf5 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -1,6 +1,7 @@
 import fs from 'fs'
 import express, { Application } from 'express'
 import config from './utilities/config'
+import { getAppPath } from './utilities/files'
 import { createServer as httpServer, Server as HTTPServer } from 'http'
 import { addHttpRoutes } from './utilities/http'
 import cors from 'cors'
@@ -14,7 +15,7 @@ import UserManager from './managers/userManager'
 import CommandManager from './managers/commandManager'
 import CharacterManager from './managers/characterManager'
 import QueueManager from './managers/queueManager'
-import { getAppPath } from './utilities/utilities'
+import DatetimeManager from './managers/datetimeManager'
 
 export class Server {
   private readonly app: Application
@@ -66,6 +67,9 @@ export class Server {
     // Load user manager
     await UserManager.boot()
 
+    // Load datetime manager
+    await DatetimeManager.boot(this.io)
+
     // Load zoneEditor manager
     await ZoneManager.boot()
 
diff --git a/src/socketEvents/disconnect.ts b/src/socketEvents/disconnect.ts
index 19f882e..4bd5acf 100644
--- a/src/socketEvents/disconnect.ts
+++ b/src/socketEvents/disconnect.ts
@@ -29,6 +29,8 @@ export default class DisconnectEvent {
         return
       }
 
+      character.resetMovement = true
+
       gameLogger.info('User disconnected along with their character')
 
       await CharacterManager.removeCharacter(character)
diff --git a/src/socketEvents/gameMaster/assetManager/object/remove.ts b/src/socketEvents/gameMaster/assetManager/object/remove.ts
index b94ce60..17d0ce9 100644
--- a/src/socketEvents/gameMaster/assetManager/object/remove.ts
+++ b/src/socketEvents/gameMaster/assetManager/object/remove.ts
@@ -3,7 +3,7 @@ import { Server } from 'socket.io'
 import { TSocket } from '../../../../utilities/types'
 import prisma from '../../../../utilities/prisma'
 import characterRepository from '../../../../repositories/characterRepository'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 interface IPayload {
   object: string
diff --git a/src/socketEvents/gameMaster/assetManager/object/upload.ts b/src/socketEvents/gameMaster/assetManager/object/upload.ts
index a7bfb0e..c42ffae 100644
--- a/src/socketEvents/gameMaster/assetManager/object/upload.ts
+++ b/src/socketEvents/gameMaster/assetManager/object/upload.ts
@@ -6,7 +6,7 @@ import prisma from '../../../../utilities/prisma'
 import sharp from 'sharp'
 import characterRepository from '../../../../repositories/characterRepository'
 import { gameMasterLogger } from '../../../../utilities/logger'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 interface IObjectData {
   [key: string]: Buffer
diff --git a/src/socketEvents/gameMaster/assetManager/sprite/create.ts b/src/socketEvents/gameMaster/assetManager/sprite/create.ts
index b9b3bf0..68ba746 100644
--- a/src/socketEvents/gameMaster/assetManager/sprite/create.ts
+++ b/src/socketEvents/gameMaster/assetManager/sprite/create.ts
@@ -3,7 +3,7 @@ import { TSocket } from '../../../../utilities/types'
 import fs from 'fs/promises'
 import prisma from '../../../../utilities/prisma'
 import characterRepository from '../../../../repositories/characterRepository'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 export default class SpriteCreateEvent {
   constructor(
diff --git a/src/socketEvents/gameMaster/assetManager/sprite/delete.ts b/src/socketEvents/gameMaster/assetManager/sprite/delete.ts
index 024336b..f346a8d 100644
--- a/src/socketEvents/gameMaster/assetManager/sprite/delete.ts
+++ b/src/socketEvents/gameMaster/assetManager/sprite/delete.ts
@@ -4,7 +4,7 @@ import fs from 'fs'
 import prisma from '../../../../utilities/prisma'
 import CharacterManager from '../../../../managers/characterManager'
 import { gameMasterLogger } from '../../../../utilities/logger'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 type Payload = {
   id: string
diff --git a/src/socketEvents/gameMaster/assetManager/sprite/update.ts b/src/socketEvents/gameMaster/assetManager/sprite/update.ts
index d23734a..5d15424 100644
--- a/src/socketEvents/gameMaster/assetManager/sprite/update.ts
+++ b/src/socketEvents/gameMaster/assetManager/sprite/update.ts
@@ -5,7 +5,7 @@ import type { Prisma, SpriteAction } from '@prisma/client'
 import { writeFile, mkdir } from 'node:fs/promises'
 import sharp from 'sharp'
 import CharacterManager from '../../../../managers/characterManager'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 type SpriteActionInput = Omit<SpriteAction, 'id' | 'spriteId' | 'frameWidth' | 'frameHeight'> & {
   sprites: string[]
diff --git a/src/socketEvents/gameMaster/assetManager/tile/delete.ts b/src/socketEvents/gameMaster/assetManager/tile/delete.ts
index f2be8de..32becbe 100644
--- a/src/socketEvents/gameMaster/assetManager/tile/delete.ts
+++ b/src/socketEvents/gameMaster/assetManager/tile/delete.ts
@@ -4,7 +4,7 @@ import { TSocket } from '../../../../utilities/types'
 import prisma from '../../../../utilities/prisma'
 import characterRepository from '../../../../repositories/characterRepository'
 import { gameMasterLogger } from '../../../../utilities/logger'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 type Payload = {
   id: string
diff --git a/src/socketEvents/gameMaster/assetManager/tile/upload.ts b/src/socketEvents/gameMaster/assetManager/tile/upload.ts
index 8c680f0..beb8ea6 100644
--- a/src/socketEvents/gameMaster/assetManager/tile/upload.ts
+++ b/src/socketEvents/gameMaster/assetManager/tile/upload.ts
@@ -5,7 +5,7 @@ import fs from 'fs/promises'
 import prisma from '../../../../utilities/prisma'
 import characterRepository from '../../../../repositories/characterRepository'
 import { gameMasterLogger } from '../../../../utilities/logger'
-import { getPublicPath } from '../../../../utilities/utilities'
+import { getPublicPath } from '../../../../utilities/files'
 
 interface ITileData {
   [key: string]: Buffer
diff --git a/src/utilities/utilities.ts b/src/utilities/files.ts
similarity index 64%
rename from src/utilities/utilities.ts
rename to src/utilities/files.ts
index 416816b..bcca0bf 100644
--- a/src/utilities/utilities.ts
+++ b/src/utilities/files.ts
@@ -1,5 +1,6 @@
 import config from './config'
 import path from 'path'
+import fs from 'fs'
 
 export function getRootPath(folder: string, ...additionalSegments: string[]) {
   return path.join(process.cwd(), folder, ...additionalSegments)
@@ -13,3 +14,20 @@ export function getAppPath(folder: string, ...additionalSegments: string[]) {
 export function getPublicPath(folder: string, ...additionalSegments: string[]) {
   return path.join(process.cwd(), 'public', folder, ...additionalSegments)
 }
+
+export function doesPathExist(path: string) {
+  try {
+    fs.accessSync(path, fs.constants.F_OK);
+    return true;
+  } catch (e) {
+    return false;
+  }
+}
+
+export function createDir(path: string) {
+  try {
+    fs.mkdirSync(path, { recursive: true });
+  } catch (e) {
+    console.error(e);
+  }
+}
\ No newline at end of file
diff --git a/src/utilities/http.ts b/src/utilities/http.ts
index e0f6433..1910678 100644
--- a/src/utilities/http.ts
+++ b/src/utilities/http.ts
@@ -12,7 +12,7 @@ import fs from 'fs'
 import zoneRepository from '../repositories/zoneRepository'
 import zoneManager from '../managers/zoneManager'
 import { httpLogger } from './logger'
-import { getPublicPath } from './utilities'
+import { getPublicPath } from './files'
 
 async function addHttpRoutes(app: Application) {
   /**
diff --git a/src/utilities/logger.ts b/src/utilities/logger.ts
index 24140be..7e5d55c 100644
--- a/src/utilities/logger.ts
+++ b/src/utilities/logger.ts
@@ -1,6 +1,6 @@
 import pino from 'pino'
 import fs from 'fs'
-import { getRootPath } from './utilities'
+import { getRootPath } from './files'
 
 // Array of log types
 const LOG_TYPES = ['http', 'game', 'gameMaster', 'app', 'queue', 'command'] as const