How would I make a timer if something stays for too long?

Hey there. I’m working on a Tower Defense game and currently it is going very well! However I am trying to make the map refresh if no players are in the elevator or in general. I have been waiting for 10 seconds in studio testing it and so far it is has not refreshed a single bit.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local MapFolder = ServerStorage:WaitForChild("MapFolder")

local Modules = ReplicatedStorage:WaitForChild("Modules")

local Elevator = script.Parent
local Config = script.Parent.Config

local DisplayScreen = Elevator:WaitForChild("Screen").Display
local SurfaceUI = DisplayScreen:WaitForChild("SurfaceGui")
local Frame = SurfaceUI:WaitForChild("ScreenUI")

local BarBG = Frame:WaitForChild("BarBG")
local Bar = BarBG:WaitForChild("Bar")

local MapBanner = Frame:WaitForChild("MapBanner")

local MapName = Frame:WaitForChild("MapChosen")
local GameMode = Frame:WaitForChild("ModeChosen")
local Status = Frame:WaitForChild("Status")

local PlayerCount = BarBG.PlayerCount

local becamezero = tick()

local MapNames = require(Modules.MapNames)

local selectedMap = MapNames.Randomize(script.Parent)
local selectedMode = MapNames.RandomMode(script.Parent)

function randomizeMap()
	local ChosenMap = MapFolder:WaitForChild(selectedMap)
	
	local ColourToTween = Config.ColourToTween 
	local MaxPlayer = ChosenMap:WaitForChild("MaxPlayers")
	local MapImage = ChosenMap:WaitForChild("MapIcon")
	
	GameMode.Text = string.upper(selectedMode)
	MapBanner.Image = MapImage.Texture
	MapName.Text = selectedMap
	
	if selectedMode == "Beginner" then
		ColourToTween.Value = Color3.fromRGB(92, 255, 74)
	elseif selectedMode == "Intermediate" then
		ColourToTween.Value = Color3.fromRGB(255, 140, 0)
	elseif selectedMode == "Hardcore" then
		ColourToTween.Value = Color3.fromRGB(255, 19, 19)
	end

	print("Randomized Map")
end

randomizeMap()

task.delay(10, function()
	if tick()-becamezero >= 10 then
		randomizeMap()
	end
end)

Bar.Changed:Connect(function()
	if Bar.Size == UDim2.new(0, 0, 1, 0) then
		becamezero = tick()
		
		task.delay(10, function()
			if tick() - becamezero >= 10 then
				randomizeMap()
			end
		end)
		
	end
end)
2 Likes

do you have a way pf detecting how many players are in the elevator?

1 Like

Yes. Heres my core script:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local TeleportService = game:GetService("TeleportService")
local TweenService = game:GetService("TweenService")

local Events = ReplicatedStorage:WaitForChild("Events")
local Modules = ReplicatedStorage:WaitForChild("Modules")
local Functions = ReplicatedStorage:WaitForChild("Functions")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")

local CameraInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local FlashInfo = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true)

local Camera = script.Parent.Camera

local safeTeleport = require(ServerScriptService.SafeTeleport)
local setDataRE = Remotes:WaitForChild("setData")

local MoveElevatorRE = Remotes:WaitForChild("MovingElevator")
local ElevatorEvent = Remotes:WaitForChild("Elevator")

local Elevator = script.Parent
local Shaft = Elevator:WaitForChild("Shaft")
local Prismatic = Shaft:WaitForChild("PrismaticConstraint")

local Config = Elevator:WaitForChild("Config")

local CountdownRunning = false
local Moving = false

local DisplayScreen = Elevator:WaitForChild("Screen").Display
local SurfaceUI = DisplayScreen:WaitForChild("SurfaceGui")
local Frame = SurfaceUI:WaitForChild("ScreenUI")

local BarBG = Frame:WaitForChild("BarBG")
local Bar = BarBG:WaitForChild("Bar")

local MapBanner = Frame:WaitForChild("MapBanner")

local MapName = Frame:WaitForChild("MapChosen")
local GameMode = Frame:WaitForChild("ModeChosen")
local Status = Frame:WaitForChild("Status")

local playersWaiting = {}

local function Setup()
	playersWaiting = {}
	Moving = false
	
	local ColourToTween = Config.ColourToTween	
	local ChosenMode = Config.MapMode.Value

	if ChosenMode == "Beginner" then
		ColourToTween.Value = Color3.fromRGB(92, 255, 74)
	elseif ChosenMode == "Intermediate" then
		ColourToTween.Value = Color3.fromRGB(255, 140, 0)
	elseif ChosenMode == "Hardcore" then
		ColourToTween.Value = Color3.fromRGB(255, 19, 19)
	end
	
	GameMode.Text = string.upper(ChosenMode)
	MapBanner.Image = Config.MapIcon.Texture
	MapName.Text = Config.MapName.Value
	
	TweenService:Create(GameMode, FlashInfo, {BackgroundColor3 = ColourToTween.Value}):Play()
		
	local Calculation = #playersWaiting / Config.MaxPlayers.Value
	TweenService:Create(Bar, CameraInfo, {Size = UDim2.new(Calculation, 0, 1, 0)}):Play()
end

local function TeleportPlayers()
	local placeId = Config.PlaceID.Value
	local server = TeleportService:ReserveServer(placeId)
	local options = Instance.new("TeleportOptions")
	options.ReservedServerAccessCode = server

	for i,v in pairs(playersWaiting) do
		setDataRE:FireClient(v, Config.MapName.Value)
	end

	safeTeleport(placeId, playersWaiting, options)
end

local function MoveElevator()
	Moving = true
	
	for i, player in pairs(playersWaiting) do
		MoveElevatorRE:FireClient(player)
	end
	
	Status.Text = "[TELEPORTING PLAYERS!]"
	
	TweenService:Create(Camera, CameraInfo, {CFrame = Camera.CFrame * CFrame.Angles(math.rad(-30), 0, 0)}):Play()
	
	Prismatic.TargetPosition = -37
	TeleportPlayers()
	script.Parent.Platform.Lower:Play()
	task.wait(10)
	script.Parent.Platform.Rise:Play()
	Prismatic.TargetPosition = 0
	task.wait(8)
	Setup()
end

local function RunCountdown()
	countdownRunning = true
	for i=10, 1, -1 do
		Status.Text = "LOWERING IN [" .. i .. "] SECONDS."
		task.wait(1)
		if #playersWaiting < 1 then
			countdownRunning = false
			Setup()
			return
		end
	end
	
	MoveElevator()
	countdownRunning = false
end

Elevator.Entrance.Touched:Connect(function(part)
	local player = Players:GetPlayerFromCharacter(part.Parent)
	local isWaiting = table.find(playersWaiting, player)

	if player and not isWaiting and #playersWaiting < Config.MaxPlayers.Value and not Moving then
		table.insert(playersWaiting, player)
		
		MapBanner.Image = Config.MapIcon.Texture
		MapName.Text = Config.MapName.Value
		
		GameMode.Text = string.upper(Config.MapMode.Value)
		
		BarBG.PlayerCount.Text = #playersWaiting .. " / " .. Config.MaxPlayers.Value
		player.Character.PrimaryPart.CFrame = Elevator.TeleportIn.CFrame
		
		local Calculation = #playersWaiting / Config.MaxPlayers.Value
		TweenService:Create(Bar, CameraInfo, {Size = UDim2.new(Calculation, 0, 1, 0)}):Play()
		
		ElevatorEvent:FireClient(player, Elevator)
		
		if not countdownRunning then
			RunCountdown()
		end
	end
end)

ElevatorEvent.OnServerEvent:Connect(function(player)
	local isWaiting = table.find(playersWaiting, player)
	if isWaiting then
		table.remove(playersWaiting, isWaiting)
	end
	
	MapBanner.Image = Config.MapIcon.Texture
	MapName.Text = Config.MapName.Value

	GameMode.Text = string.upper(Config.MapMode.Value)

	BarBG.PlayerCount.Text = #playersWaiting .. " / " .. Config.MaxPlayers.Value
	player.Character.PrimaryPart.CFrame = Elevator.TeleportIn.CFrame
	
	local Calculation = #playersWaiting / Config.MaxPlayers.Value
	TweenService:Create(Bar, CameraInfo, {Size = UDim2.new(Calculation, 0, 1, 0)}):Play()
	
	if player.Character then
		player.Character.PrimaryPart.CFrame = workspace.TeleportOut.CFrame
	end
end)

Setup()

Events.RefreshMap.Event:Connect(Setup)
3 Likes

can you put the player amount on the other script?

1 Like

Using the barsize. I’m able to tell how many players are in the elevator. I can check if there are no players by checking if its size is Udim2.new(0, 0, 1, 0)

I rthink you can fix it with a repeat loop in the bar.changed function after the if statement put

local checkamnt = 0
repeat
wait(0.1)
checkamnt = checkamt + 1
until checkamnt = 100 or Bar.Size ~= Udim2.new(0,0,1,0)
if Bar.Size == Udim2.new(0,0,1,0) then
randomizemap()
end
checkamnt = 0

It sort of works. It only seems to randomize 4 times before stopping.

It weirdly does 4 at a time… Here’s my current script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local MapFolder = ServerStorage:WaitForChild("MapFolder")

local Modules = ReplicatedStorage:WaitForChild("Modules")

local Elevator = script.Parent
local Config = script.Parent.Config
local MaxWait = 10

local DisplayScreen = Elevator:WaitForChild("Screen").Display
local SurfaceUI = DisplayScreen:WaitForChild("SurfaceGui")
local Frame = SurfaceUI:WaitForChild("ScreenUI")

local BarBG = Frame:WaitForChild("BarBG")
local Bar = BarBG:WaitForChild("Bar")

local MapBanner = Frame:WaitForChild("MapBanner")

local MapName = Frame:WaitForChild("MapChosen")
local GameMode = Frame:WaitForChild("ModeChosen")
local Status = Frame:WaitForChild("Status")

local PlayerCount = BarBG.PlayerCount

local MapNames = require(Modules.MapNames)

local selectedMap = MapNames.Randomize(script.Parent)
local selectedMode = MapNames.RandomMode(script.Parent)

function randomizeMap()
	local ChosenMap = MapFolder:WaitForChild(selectedMap)
	
	local ColourToTween = Config.ColourToTween 
	local MaxPlayer = ChosenMap:WaitForChild("MaxPlayers")
	local MapImage = ChosenMap:WaitForChild("MapIcon")
	
	GameMode.Text = string.upper(selectedMode)
	MapBanner.Image = MapImage.Texture
	MapName.Text = selectedMap
	
	if selectedMode == "Beginner" then
		ColourToTween.Value = Color3.fromRGB(92, 255, 74)
	elseif selectedMode == "Intermediate" then
		ColourToTween.Value = Color3.fromRGB(255, 140, 0)
	elseif selectedMode == "Hardcore" then
		ColourToTween.Value = Color3.fromRGB(255, 16, 16)
	end

	print("Randomized Map")
end

randomizeMap()

Timer = 0

Bar.Changed:Connect(function()
	if Bar.Size == UDim2.new(0, 0, 1, 0) then	
		
		repeat task.wait(1)
			Timer += 1
			print(Timer)
		until Timer == MaxWait or Bar.Size ~= UDim2.new(0, 0, 1, 0)

		
		if Bar.Size == UDim2.new(0,0,1,0) then
			randomizeMap()
		end
		
		task.wait(1)
		Timer = 0
	end
end)
1 Like

maybe move the timer = 0 to betweenthe until and if statement. and put under the time = 0 a task.wait()

It works pretty well! But it doesn’t seem to repeat again after… I edited the last message to show the new code.

maybe in the randomize map function put a variable that adds up once each time. and in the if statent that randmizes the map change it to

repeat task.wait(0.01)
randomizeMap()
until (your variable) == 2
(variable) =1

— it goes up to 2 because ypu randomize it before

Like this?

while true do
	if Variable == 2 then
		randomizeMap()
		Variable = 1
	end
	task.wait(0.01)
end

like this:

repeat task.wait(0.01)
randomizeMap()
until (your variable) == 2
(variable) =1

basically how it
works is that it does randomiz map and randomiza map has a variable that adds by one when it starts. so it checks if it even started by breaking the function if the variable reaches 2 meaning that randomaize map triggered

I’m still a bit confused by how to do it…

EDIT: I’ve sort of understood it. Here’s my new script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local MapFolder = ServerStorage:WaitForChild("MapFolder")

local Modules = ReplicatedStorage:WaitForChild("Modules")

local Elevator = script.Parent
local Config = script.Parent.Config
local MaxWait = 10

local DisplayScreen = Elevator:WaitForChild("Screen").Display
local SurfaceUI = DisplayScreen:WaitForChild("SurfaceGui")
local Frame = SurfaceUI:WaitForChild("ScreenUI")

local BarBG = Frame:WaitForChild("BarBG")
local Bar = BarBG:WaitForChild("Bar")

local MapBanner = Frame:WaitForChild("MapBanner")

local MapName = Frame:WaitForChild("MapChosen")
local GameMode = Frame:WaitForChild("ModeChosen")
local Status = Frame:WaitForChild("Status")

local PlayerCount = BarBG.PlayerCount

local MapNames = require(Modules.MapNames)

local selectedMap = MapNames.Randomize(script.Parent)
local selectedMode = MapNames.RandomMode(script.Parent)

local Variable = 1
local Randomized = false

function randomizeMap()	
	if not Randomized then
		Randomized = true
		
		local ChosenMap = MapFolder:WaitForChild(selectedMap)

		local ColourToTween = Config.ColourToTween 
		local MaxPlayer = ChosenMap:WaitForChild("MaxPlayers").Value
		local MapImage = ChosenMap:WaitForChild("MapIcon")

		if selectedMode == "Beginner" then
			ColourToTween.Value = Color3.fromRGB(92, 255, 74)
		elseif selectedMode == "Intermediate" then
			ColourToTween.Value = Color3.fromRGB(255, 140, 0)
		elseif selectedMode == "Hardcore" then
			ColourToTween.Value = Color3.fromRGB(255, 16, 16)
		end
		
		GameMode.Text = string.upper(selectedMode)
		MapBanner.Image = MapImage.Texture
		MapName.Text = selectedMap

		print("Randomized Map")
		
		ReplicatedStorage.Events.RefreshMap:Fire()
		
		task.wait(10)
		Randomized = false
		Variable = 1
	end
end

repeat task.wait(0.001)
	
	if Bar.Size == UDim2.new(0, 0, 1, 0) then
		randomizeMap()
	end
	
until Variable == 2
```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

local MapFolder = ServerStorage:WaitForChild("MapFolder")

local MapNames = {	
	"Grass Lands",
	"Nuclear Bunker",
	"Infiltration"
}

local Modes = {
	"Beginner",
	"Intermediate",
	"Hardcore",
}

function MapNames.Randomize(elevator)
	local selectedMap = MapNames[math.random(1,  #MapNames)]		
	local realMap = MapFolder:FindFirstChild(selectedMap)
	
	return realMap.Name
end

function MapNames.RandomMode(elevator)
	local selectedMode = Modes[math.random(1, #Modes)]
	return selectedMode
end

return MapNames

nevermind that I remembered that there is this roblox issue that sometimes ibstead of adding 1 it adds 1.0000001 or 0.9999999 so in ur repeat loop instead of making the loop break if the timer is == to the max u shoukd make it timer >= maxwait. if it doesnt work then I could explain the other repeat loop

I’ll try that now. sampletextsampletext

I see it as a complication of life, why not index the value, I think it will be necessary in the future.

What do you mean by index?

eeeeeee

your translation I think is wrong, index = access the variable or the exact value of the players or that changes the scaling of the bar.

HAHAHA, you got the account wrong, the resemblance is unmatched.

1 Like

Thank you! I’ll mark your point as the solution