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.