How can i make loaded Swimmable Parts?

Ive made a script that chooses random maps that load in the game in certain periods of time and i want to add swimmable water zones to the maps, does anyone know how i can do this?
This is the server script that picks the maps

local LobbyMinutes = 0
local LobbySeconds = 5

local GameMinutes = 4
local GameSeconds = 30

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinEvent = game:GetService("ServerStorage"):FindFirstChild("CoinEvent")
local multEvent = game:GetService("ServerStorage"):FindFirstChild("MultEvent")
local waterEvent = game:GetService("ReplicatedStorage"):FindFirstChild("Remotes"):FindFirstChild("WaterEvent")
local deletecoinsevent = game:GetService("ServerStorage"):FindFirstChild("DeleteCoinsEvent")
local deletemultsevent = game:GetService("ServerStorage"):FindFirstChild("DeleteMultEvent")
local TimerValues = ReplicatedStorage:WaitForChild("TimerValues")
local waterevent = ReplicatedStorage.Remotes:WaitForChild("WaterEvent")
local gameTimer = TimerValues.GameTimer
local lobbyTimer = TimerValues.LobbyTimer
local finishline = script.Parent -- Change this
local placements = {}
local enableevent = ReplicatedStorage.Remotes.PEnableEvent
local disableevent = ReplicatedStorage.Remotes.PDisableEvent
local placeevent = game.ReplicatedStorage.Remotes.PlacementEvent
local Players = game:GetService("Players")

local TweenService = game:GetService("TweenService")
local FadeInfo = TweenInfo.new(1.3,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

function teleportPlayers(RP,SpawnPart)
	if RP ~= nil then
		if SpawnPart ~= nil then
			RP.CFrame = SpawnPart.CFrame
		end
	end
end


game.ReplicatedStorage:FindFirstChild("Remotes"):FindFirstChild("GetPoints").OnServerEvent:Connect(function(Player,Point)
	local PlayerPoint = Player:FindFirstChild("Points")
	if PlayerPoint ~= nil then
		PlayerPoint.Value = Point
	end
end)


while true do
	lobbyTimer.Minutes.Value = LobbyMinutes
	lobbyTimer.Seconds.Value = LobbySeconds

	repeat wait(1)
		if lobbyTimer.Seconds.Value > 0 then
			lobbyTimer.Seconds.Value -= 1
		else
			if lobbyTimer.Minutes.Value > 0 then
				lobbyTimer.Minutes.Value -= 1
				lobbyTimer.Seconds.Value = 59
			end
		end
	until lobbyTimer.Minutes.Value == 0 and lobbyTimer.Seconds.Value == 0
	
	local MapstoCoins = {
		["SnowMap1"] = "CoinSpawnSnow",
		["DesertMap1"] = "CoinSpawnDesert",
		["BeachMap1"] = "CoinSpawnBeach",
		["ForestMap1"] = "CoinSpawnForest"
	}
	local MapstoLobby = {
		["SnowMap1"] = "SnowLobby",
		["DesertMap1"] = "DesertLobby",
		["BeachMap1"] = "BeachLobby",
		["ForestMap1"] = "ForestLobby"
	}
	local MapstoMult = {
		["DesertMap1"] = "MultSpawnDesert",
		["SnowMap1"] = "MultSpawnSnow",
		["BeachMap1"] = "MultSpawnBeach",
		["ForestMap1"] = "MultSpawnForest"
	}
	

	local mapHolder = game:GetService("ServerStorage").MapHolder
	local coinsHolder = game:GetService("ServerStorage").CoinsHolder
	local lobbyHolder = game:GetService("ServerStorage").LobbyHolder
	local multHolder = game:GetService("ServerStorage").MultHolder
	local waterHolder = game:GetService("ServerStorage").WaterHolder
	local Children = mapHolder:GetChildren()
	local CoinChildren = coinsHolder:GetChildren()
	local LobChildren = lobbyHolder:GetChildren()
	local MultChildren = multHolder:GetChildren()
	local Index = math.random(1,#Children)
	local randomInt = Children[Index]

	local finalMap = mapHolder:FindFirstChild(randomInt.Name):Clone()  
	for _,coinmaps in pairs(CoinChildren) do
		if coinmaps.Name == MapstoCoins[randomInt.Name] then
			local finalcoinMap = coinmaps:Clone()
			for _,lobmaps in pairs(LobChildren) do
				if lobmaps.Name == MapstoLobby[randomInt.Name] then
					local finalobby = lobmaps:Clone()
					for _,multmap in pairs(MultChildren) do
						if multmap.Name == MapstoMult[randomInt.Name] then
							local finalmultMap = multmap:Clone()
	finalcoinMap.Parent = workspace.ChosenCoinMap
	finalmultMap.Parent = workspace.ChosenMultMap
	finalobby.Parent = workspace
	coinEvent:Fire(coinmaps)
	multEvent:Fire(multmap)
	finalMap.Parent = workspace
	
	

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('HumanoidRootPart') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local NewValue = Instance.new("BoolValue")
				NewValue.Name = "Ingame"
				NewValue.Parent = LocalPlayer.Character
				NewValue.Value = false

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)
				-- goes to riderhandler and highperfomance water
		enableevent:FireClient(LocalPlayer, finalMap)
										
				

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					teleportPlayers(LocalPlayer.Character.HumanoidRootPart,finalMap:FindFirstChild('SpawnPart'))
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
					end)
				end)
			end
		end
	end

	wait(1.6 + 2)

	gameTimer.Minutes.Value = GameMinutes
	gameTimer.Seconds.Value = GameSeconds

	repeat wait(1)
		if gameTimer.Seconds.Value > 0 then
			gameTimer.Seconds.Value -= 1
		else
			if gameTimer.Minutes.Value > 0 then
				gameTimer.Minutes.Value -= 1
				gameTimer.Seconds.Value = 59
			end
		end
	until gameTimer.Minutes.Value == 0 and gameTimer.Seconds.Value == 0

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('Ingame') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					LocalPlayer:LoadCharacter()
					teleportPlayers(LocalPlayer.Character.HumanoidRootPart,game.Workspace.GameEndSpawn)
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
												
					
					end)
				end)
			end
		end
	end
	
	
	game.ReplicatedStorage:FindFirstChild("Remotes"):FindFirstChild("GetPoints"):FireAllClients()
	
	task.wait(2.5)
	
	local placements = {}
	for i,plr in pairs(game.Players:GetPlayers()) do
		table.insert(placements,{['Player'] = plr,['Points'] = plr.Points.Value})
	end
	
	table.sort(placements,function(a,b)
		return a.Points > b.Points
	end)
							placeevent:FireAllClients({placements[1],placements[2],placements[3],placements[4],placements[5],placements[6],placements[7],placements[8],placements[9],placements[10],placements[11],placements[12],placements[13],placements[14],placements[15],placements[16],placements[17],placements[18],placements[19],placements[20]})
	
	for _,GetPl in pairs(Players:GetPlayers()) do
		--goes to riderhandler
		disableevent:FireClient(GetPl)
		GetPl.Points.Value = 0
		GetPl.PointMultiply.Value = 0
	end
	wait(1.6)
	deletecoinsevent:Fire()
	deletemultsevent:Fire()
	finalMap:Destroy()
	finalcoinMap:Destroy()
	finalobby:Destroy()
	finalmultMap:Destroy()
	wait(3)
						end
						end
		end
	end
		end
	end
	end

Screenshot 2024-12-04 192433

I tried filling water terrain in the maps although when they are supposed to load in, the script just breaks and stops working instead of making the terrain load with the map

What do you mean by “breaks”? Were there errors?

Working for me. Just initialize your water at the start and store it, then paste it into the world every time you load a new map. Using Copy+Paste will let you make easy adjustments and more complex water shapes without having to manually fill in blocks.

It did break, and it said the script said it had to timeout in the output because the screen was frozen
I made a script in a part where when the server starts, it fills in water terrain with the inside of the part


But when i put this inside the map and let it load, thats when the map randomiser script breaks

first clip is the water filling part being put in the workspace by itself, and the map randomiser is disabled and the second clip is the map randomiser script being enabled and the water filling part being placed inside the map

The map appears to contain a significant number of parts. The freezing looks like it’s probably just overwhelming your computer and causing a host of scripts to timeout (I assume the freeze happens irrespective of whether the water script is on or off?). Have you considered spawning the maps in iteratively with waits to allow the server/clients to keep up (i.e. Rather than just copy+pasting the entire model into the workspace you loop through all of its descendant parts/models and move them one at a time into the workspace?

This freezing only happens for the maps i want to add the water block in, the ones without it have no problem with loading and dont freeze, although how can i loop through the descendants of the parts and models and move them into the workspace one at a time like you said?

If the map model is broken up into different parts and models (i.e. each tree is its own model) then you can do something really simple:

local function SpawnMap(MapModel)
    local newMap = Instance.new('Model', workspace.Maps); -- New 'map' model in workspace
    for _,Child in pairs(MapModel:GetChildren()) do
        Child:Clone().Parent = newMap;
        task.wait(); -- Add a small wait just to allow the server to catch up
    end
end

This is my assumption at what the issue is at least. You’re getting a lot of timeout errors and they tend to only appear when the server is under immense strain such that a bunch of execution frames are getting skipped. You say:

only happens for the maps i want to add the water block in

I assume by this you mean those specific maps have issues, even when you’re not trying to spawn in water. Do these specific maps have significantly more parts than the others? If not, and it stops freezing when you don’t try to spawn water into those maps, then it could be an issue with the terrain.

See this post: Extreme amounts of lag when maps (>1000 parts) are parented to workspace - #10 by 7z99

I tried putting the water block in the other maps that dont have any needed water blocks, and they didnt freeze the game it loaded fine with the water terrain spawning in as well, so i think its just something in that specific map itself thats making it freeze the game

Okay, so like I said, unless there’s other scripts inside the map model that’s causing it to lag spike on creation, then my assumption is that it’s purely an issue with the large number of parts being created in a single instant that’s freezing the server and causing the other scripts to time out. I’d recommend utilising some optimisation techniques such as the loop method I mentioned earlier to slow down the part creation and prevent the server from freezing every time a new map loads. That should solve a lot of issues. Grouping the map into separate models and cloning each model individually at a time with a short wait inbetween should suffice.

I tried the loop method that spawns in the models parts one at a time, it works and loads in perfectly but when the round ends for another map to be spawned in, how can i despawn/destroy it and the water terrain? since when i used the normal :destroy() to the folder inside the model, nothing happened and the intermission timer breaks
Screenshot 2024-12-04 231405

Did you forget an end after your for loop? Or is the intention to iterate through CoinChildren every time you spawn in a new segment of your map?

Also when it despawns are you sure you’re destroying the newMap? I don’t see where you re-assign the newly created map to the finalMap variable.

You can remove all terrain from the map through: workspace.Terrain:Clear()

I’ve already added an end its just outside the picture, and coinchildren and multchildren and lobchildren are needed to spawn with the map to also spawn the coins, stars, and the new lobby specified to that map
how can i fix this problem of the intermission timer not working anymore?

Have you tried printing: gameTimer.Minutes.Value and gameTimer.Seconds.Value at the start of the repeat to check that it’s being a) set correctly, and b) reduced correctly?

If not, then paste your full code again so I can check it.

local LobbyMinutes = 0
local LobbySeconds = 10

local GameMinutes = 0
local GameSeconds = 5

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinEvent = game:GetService("ServerStorage"):FindFirstChild("CoinEvent")
local multEvent = game:GetService("ServerStorage"):FindFirstChild("MultEvent")
local waterEvent = game:GetService("ReplicatedStorage"):FindFirstChild("Remotes"):FindFirstChild("WaterEvent")
local deletecoinsevent = game:GetService("ServerStorage"):FindFirstChild("DeleteCoinsEvent")
local deletemultsevent = game:GetService("ServerStorage"):FindFirstChild("DeleteMultEvent")
local TimerValues = ReplicatedStorage:WaitForChild("TimerValues")
local waterevent = ReplicatedStorage.Remotes:WaitForChild("WaterEvent")
local gameTimer = TimerValues.GameTimer
local lobbyTimer = TimerValues.LobbyTimer
local finishline = script.Parent -- Change this
local placements = {}
local enableevent = ReplicatedStorage.Remotes.PEnableEvent
local disableevent = ReplicatedStorage.Remotes.PDisableEvent
local placeevent = game.ReplicatedStorage.Remotes.PlacementEvent
local Players = game:GetService("Players")

local TweenService = game:GetService("TweenService")
local FadeInfo = TweenInfo.new(1.3,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false,0)

function teleportPlayers(RP,SpawnPart)
	if RP ~= nil then
		if SpawnPart ~= nil then
			RP.CFrame = SpawnPart.CFrame
		end
	end
end


game.ReplicatedStorage:FindFirstChild("Remotes"):FindFirstChild("GetPoints").OnServerEvent:Connect(function(Player,Point)
	local PlayerPoint = Player:FindFirstChild("Points")
	if PlayerPoint ~= nil then
		PlayerPoint.Value = Point
	end
end)


while true do
	lobbyTimer.Minutes.Value = LobbyMinutes
	lobbyTimer.Seconds.Value = LobbySeconds

	repeat wait(1)
		print(lobbyTimer.Seconds.Value)
		if lobbyTimer.Seconds.Value > 0 then
			lobbyTimer.Seconds.Value -= 1
		else
			if lobbyTimer.Minutes.Value > 0 then
				lobbyTimer.Minutes.Value -= 1
				lobbyTimer.Seconds.Value = 59
			end
		end
	until lobbyTimer.Minutes.Value == 0 and lobbyTimer.Seconds.Value == 0
	
	local MapstoCoins = {
		["SnowMap1"] = "CoinSpawnSnow",
		["DesertMap1"] = "CoinSpawnDesert",
		["BeachMap1"] = "CoinSpawnBeach",
		["ForestMap1"] = "CoinSpawnForest"
	}
	local MapstoLobby = {
		["SnowMap1"] = "SnowLobby",
		["DesertMap1"] = "DesertLobby",
		["BeachMap1"] = "BeachLobby",
		["ForestMap1"] = "ForestLobby"
	}
	local MapstoMult = {
		["DesertMap1"] = "MultSpawnDesert",
		["SnowMap1"] = "MultSpawnSnow",
		["BeachMap1"] = "MultSpawnBeach",
		["ForestMap1"] = "MultSpawnForest"
	}
	

	local mapHolder = game:GetService("ServerStorage").MapHolder
	local coinsHolder = game:GetService("ServerStorage").CoinsHolder
	local lobbyHolder = game:GetService("ServerStorage").LobbyHolder
	local multHolder = game:GetService("ServerStorage").MultHolder
	local waterHolder = game:GetService("ServerStorage").WaterHolder
	local Children = mapHolder:GetChildren()
	local CoinChildren = coinsHolder:GetChildren()
	local LobChildren = lobbyHolder:GetChildren()
	local MultChildren = multHolder:GetChildren()
	local Index = math.random(1,#Children)
	local randomInt = Children[Index]
	
		local newMap = Instance.new("Model", workspace); -- New 'map' model in workspace
		for _,finalMap in pairs(mapHolder:FindFirstChild(randomInt.Name):GetChildren()) do
			finalMap:Clone().Parent = newMap;
			task.wait(); -- Add a small wait just to allow the server to catch up
		
	for _,coinmaps in pairs(CoinChildren) do
		if coinmaps.Name == MapstoCoins[randomInt.Name] then
			local finalcoinMap = coinmaps:Clone()
			for _,lobmaps in pairs(LobChildren) do
				if lobmaps.Name == MapstoLobby[randomInt.Name] then
					local finalobby = lobmaps:Clone()
					for _,multmap in pairs(MultChildren) do
						if multmap.Name == MapstoMult[randomInt.Name] then
							local finalmultMap = multmap:Clone()
							
	finalcoinMap.Parent = workspace.ChosenCoinMap
	finalmultMap.Parent = workspace.ChosenMultMap
	finalobby.Parent = workspace
	coinEvent:Fire(coinmaps)
	multEvent:Fire(multmap)
	
	print(finalMap.Name)
	
	

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('HumanoidRootPart') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local NewValue = Instance.new("BoolValue")
				NewValue.Name = "Ingame"
				NewValue.Parent = LocalPlayer.Character
				NewValue.Value = false

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)
				-- goes to riderhandler and highperfomance water
		enableevent:FireClient(LocalPlayer, finalMap)
										
				

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					teleportPlayers(LocalPlayer.Character.HumanoidRootPart,finalMap:FindFirstChild('SpawnPart'))
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
					end)
				end)
			end
		end
	end

	wait(1.6 + 2)

	gameTimer.Minutes.Value = GameMinutes
	gameTimer.Seconds.Value = GameSeconds

	repeat wait(1)
		if gameTimer.Seconds.Value > 0 then
			gameTimer.Seconds.Value -= 1
		else
			if gameTimer.Minutes.Value > 0 then
				gameTimer.Minutes.Value -= 1
				gameTimer.Seconds.Value = 59
			end
		end
	until gameTimer.Minutes.Value == 0 and gameTimer.Seconds.Value == 0

	for _, LocalPlayer in pairs(game:GetService("Players"):GetChildren()) do
		if LocalPlayer.Character then
			if LocalPlayer:FindFirstChild('PlayerGui') and LocalPlayer.Character:FindFirstChild('Ingame') then
				local GUI = Instance.new("ScreenGui")
				GUI.Name = "Fade"
				GUI.Parent = LocalPlayer.PlayerGui
				GUI.ResetOnSpawn = false
				GUI.IgnoreGuiInset = true
				GUI.Enabled = true

				local Frame = Instance.new("Frame")
				Frame.Parent = GUI 
				Frame.BackgroundTransparency = 1
				Frame.BackgroundColor3 = Color3.fromRGB(0,0,0)
				Frame.Visible = true
				Frame.Size = UDim2.new(1,0,1,0)
				Frame.Position = UDim2.new(0,0,0,0)

				local TweenIn = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 0})
				TweenIn:Play()

				TweenIn.Completed:Connect(function()
					LocalPlayer:LoadCharacter()
					teleportPlayers(LocalPlayer.Character.HumanoidRootPart,game.Workspace.GameEndSpawn)
					wait(2)
					local TweenOut = TweenService:Create(Frame,FadeInfo,{BackgroundTransparency = 1})
					TweenOut:Play()

					TweenOut.Completed:Connect(function()
						GUI:Destroy()
												
					
					end)
				end)
			end
		end
	end
	
	
	game.ReplicatedStorage:FindFirstChild("Remotes"):FindFirstChild("GetPoints"):FireAllClients()
	
	task.wait(2.5)
	
	local placements = {}
	for i,plr in pairs(game.Players:GetPlayers()) do
		table.insert(placements,{['Player'] = plr,['Points'] = plr.Points.Value})
	end
	
	table.sort(placements,function(a,b)
		return a.Points > b.Points
	end)
							placeevent:FireAllClients({placements[1],placements[2],placements[3],placements[4],placements[5],placements[6],placements[7],placements[8],placements[9],placements[10],placements[11],placements[12],placements[13],placements[14],placements[15],placements[16],placements[17],placements[18],placements[19],placements[20]})
	
	for _,GetPl in pairs(Players:GetPlayers()) do
		--goes to riderhandler
		disableevent:FireClient(GetPl)
		GetPl.Points.Value = 0
		GetPl.PointMultiply.Value = 0
	end
	wait(1.6)
	deletecoinsevent:Fire()
	deletemultsevent:Fire()
	newMap:FindFirstChild(finalMap.Name):Destroy()
	finalcoinMap:Destroy()
	finalobby:Destroy()
	finalmultMap:Destroy()
	game.Workspace.Terrain:Clear()
	wait(3)
	end
						end
						end
		end
	end
		end
	end
	end

You’ve set ‘GameMinutes’ to 0 and ‘GameSeconds’ to 5, which means the game will only last 5 seconds.

Edit: nvm, misread your question. Let me have another look.

So I’m pretty sure this is still the issue. Your end is in the wrong place.

In your original script, the line:

local finalMap = mapHolder:FindFirstChild(randomInt.Name):Clone() 

Should’ve been replaced with:

local newMap = Instance.new("Model", workspace); -- New 'map' model in workspace
for _,SectionOfFinalMap in pairs(mapHolder:FindFirstChild(randomInt.Name):GetChildren()) do
	finalMap:Clone().Parent = newMap;
	task.wait(); -- Add a small wait just to allow the server to catch up
end

Then at the end where you do finalMap:Destroy(), instead do:

newMap:Destroy();

Sorry for respond late, I went to bed after since it was midnight but i implemented the new script and the randomising maps and spawning in swimmable parts works now, thanks for the help

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.