The error message suggests that the SkyboxChangeEvent is being fired too frequently, causing the event queue to be exhausted. This is likely happening because we're firing the event every time a player touches any part of the road, which can occur multiple times per second. Let's optimize this by introducing a cooldown and only firing the event when the biome actually changes. Here's the updated script:
-- ServerScriptService for road generation local Workspace = game:GetService("Workspace") local Lighting = game:GetService("Lighting") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RoadTemplates = { Normal1 = Workspace.Road, Normal2 = Workspace.Road2, Normal3 = Workspace.Road3, Normal4 = Workspace.Road4, Normal5 = Workspace.Road5, Desert = Workspace.DesertRoad, Snow = Workspace.SnowRoad, Bridge = Workspace.BridgeRoad, Bloody = Workspace.BLOODYROAD, } local offsetX = 50 local lastXPosition = 0 local currentBiome = "Normal1" local cloneCount = 0 local firstPlayerJoined = false -- Create a RemoteEvent for client-side skybox changes local SkyboxChangeEvent = Instance.new("RemoteEvent") SkyboxChangeEvent.Name = "SkyboxChangeEvent" SkyboxChangeEvent.Parent = ReplicatedStorage local function getRandomBiomeLength() return math.random(30, 70) -- Variable biome length between 30 and 70 segments end local function getNextBiome() local biomes = {"Normal1", "Normal2", "Normal3", "Normal4", "Normal5", "Desert", "Snow", "Bloody"} return biomes[math.random(#biomes)] end local function CloneRoom(xOffset, roomTemplate) local newRoom = roomTemplate:Clone() newRoom.Parent = Workspace for _, part in ipairs(newRoom:GetDescendants()) do if part:IsA("BasePart") then part.CFrame = part.CFrame + Vector3.new(xOffset, 0, 0) end end return newRoom end local playerBiomes = {} local biomeChangeCooldown = {} local function SetPlayerBiome(player, newBiome) if playerBiomes[player] ~= newBiome and (not biomeChangeCooldown[player] or tick() - biomeChangeCooldown[player] > 1) then playerBiomes[player] = newBiome biomeChangeCooldown[player] = tick() if newBiome == "Bloody" then SkyboxChangeEvent:FireClient(player, true) else SkyboxChangeEvent:FireClient(player, false) end end end local function GenerateRoads() local biomeLength = getRandomBiomeLength() local bridgeGenerated = false local currentBiomeInstance = nil while true do if currentBiome == "Bridge" and not bridgeGenerated then currentBiomeInstance = CloneRoom(lastXPosition, RoadTemplates.Bridge) lastXPosition += offsetX cloneCount += 1 bridgeGenerated = true else currentBiomeInstance = CloneRoom(lastXPosition, RoadTemplates[currentBiome]) lastXPosition += offsetX cloneCount += 1 if cloneCount >= biomeLength then if math.random() < 0.1 then -- 10% chance for a bridge currentBiome = "Bridge" bridgeGenerated = false else currentBiome = getNextBiome() end biomeLength = getRandomBiomeLength() cloneCount = 0 end end -- Set up TouchedEvent for the new biome instance if currentBiomeInstance then for _, part in ipairs(currentBiomeInstance:GetDescendants()) do if part:IsA("BasePart") then part.Touched:Connect(function(hit) local player = game.Players:GetPlayerFromCharacter(hit.Parent) if player then SetPlayerBiome(player, currentBiome) end end) end end end task.wait(1) -- Using task.wait() for more consistent timing end end game.Players.PlayerAdded:Connect(function(player) if not firstPlayerJoined then firstPlayerJoined = true task.wait(5) GenerateRoads() end -- Set up client-side skybox changes local function onSkyboxChange(isBloody) if isBloody then -- Set bloody skybox and atmosphere Lighting.Ambient = Color3.new(1, 0, 0) Lighting.OutdoorAmbient = Color3.new(1, 0, 0) Lighting.ColorShift_Bottom = Color3.new(1, 0, 0) Lighting.ColorShift_Top = Color3.new(1, 0, 0) else -- Set normal skybox and atmosphere Lighting.Ambient = Color3.new(0.5, 0.5, 0.5) Lighting.OutdoorAmbient = Color3.new(0.5, 0.5, 0.5) Lighting.ColorShift_Bottom = Color3.new(0, 0, 0) Lighting.ColorShift_Top = Color3.new(0, 0, 0) end end SkyboxChangeEvent.OnClientEvent:Connect(onSkyboxChange) end) game.Players.PlayerRemoving:Connect(function(player) playerBiomes[player] = nil biomeChangeCooldown[player] = nil end)
These changes should significantly reduce the number of remote events being fired, preventing the "Remote event invocation queue exhausted" error. The skybox will now only change when a player moves to a different biome, and there's a cooldown to prevent rapid changes.