--[[ 99 Nights - A Roblox Luau Adaptation Based on the classic "99 Nights" game concept ]] local ServerScriptService = game:GetService("ServerScriptService") local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") -- Module dependencies local EnemySpawner = require(script.EnemySpawner) local WaveManager = require(script.WaveManager) local PlayerManager = require(script.PlayerManager) -- Configuration local CONFIG = { TotalNights = 99, NightDuration = 120, -- seconds per night BreakTime = 30, -- seconds between nights MaxEnemies = 50, SpawnRadius = 100, EnemyTypes = { {Name = "Goblin", Health = 50, Damage = 10, Speed = 16, Reward = 10}, {Name = "Orc", Health = 100, Damage = 20, Speed = 12, Reward = 20}, {Name = "Troll", Health = 200, Damage = 30, Speed = 8, Reward = 30}, {Name = "Demon", Health = 500, Damage = 50, Speed = 14, Reward = 50} } } -- Game State local GameState = { CurrentNight = 0, IsNight = false, IsGameOver = false, TotalEnemiesKilled = 0, TotalScore = 0 } -- Initialize Remote Events/Functions local RemoteEvents = { UpdateNight = Instance.new("RemoteEvent"), UpdateScore = Instance.new("RemoteEvent"), GameOver = Instance.new("RemoteEvent"), EnemySpawned = Instance.new("RemoteEvent"), EnemyKilled = Instance.new("RemoteEvent") } for name, event in pairs(RemoteEvents) do event.Name = name event.Parent = ReplicatedStorage end -- Main Game Manager local GameManager = {} GameManager.__index = GameManager function GameManager.new() local self = setmetatable({}, GameManager) self.State = table.clone(GameState) self.Enemies = {} self.Players = {} self.WaveManager = WaveManager.new(CONFIG) self.EnemySpawner = EnemySpawner.new(CONFIG, self.Enemies) return self end function GameManager:StartGame() print("Starting 99 Nights!") -- Connect player events Players.PlayerAdded:Connect(function(player) self:OnPlayerAdded(player) end) Players.PlayerRemoving:Connect(function(player) self:OnPlayerRemoved(player) end) -- Start first night task.wait(5) -- Initial countdown self:StartNight() end function GameManager:StartNight() if self.State.CurrentNight >= CONFIG.TotalNights then self:GameOver(true) return end self.State.CurrentNight += 1 self.State.IsNight = true self.State.NightStartTime = tick() print(string.format("Night %d has begun!", self.State.CurrentNight)) -- Notify all players RemoteEvents.UpdateNight:FireAllClients(self.State.CurrentNight, true) -- Start enemy spawning self.WaveManager:StartWave(self.State.CurrentNight) -- Night timer task.delay(CONFIG.NightDuration, function() if self.State.IsNight then self:EndNight() end end) end function GameManager:EndNight() if not self.State.IsNight then return end self.State.IsNight = false self.State.TotalEnemiesKilled += self.WaveManager:GetKilledCount() print(string.format("Night %d completed! Score: %d", self.State.CurrentNight, self.State.TotalScore)) RemoteEvents.UpdateNight:FireAllClients(self.State.CurrentNight, false) -- Check for survival bonus local alivePlayers = self:GetAlivePlayers() if