Why is this sending a ton of requests to the module scripts?

  1. I want my script to stop looping and sending 800 requests to this module script

mainscript:

wait(2)
local Players = game.Players
local ReplicatedStorage = game.ReplicatedStorage
local ServerStorage = game.ServerStorage
local ChangeText = game.ReplicatedStorage.ChangeText
local InGame = game.ServerStorage.Values.InGame
local PlayersLeft = game.ServerStorage.Values.PlayersLeft
local Functions = require(script.Functions)

while true do
	ChangeText:FireAllClients("Waiting for 2 players")
	repeat wait() until #game.Players:GetPlayers() >= 2
	local Functions = require(script.Functions)
	ChangeText:FireAllClients("Starting")
	wait(7)
	Functions.SetPlayersLeftValue()
	
	
	for _, player in pairs(Players:GetPlayers()) do
		Functions.SpawnPlayerValue(player, false)
	end
	
	Functions.resetKills()
	
	wait(3)
	
	ChangeText:FireAllClients("Loading Map")
	
	wait(3)
	
	Functions.TeleportPlayer()
	
	ChangeText:FireAllClients("")
	
	wait(5)

	Functions.GetPlayerKnifesAndGiveItToThem()
	
	repeat wait() until game.ServerStorage.Values.PlayersLeft.Value <= 1
	
	game.ServerStorage.Values.PlayersLeft.Value = 0
	
	ChangeText:FireAllClients("Game Over!")
	
	wait(7)
	
	Functions.KillPlayers()
end

Module script:

local Functions = {}

function Functions.resetKills()
	for _, player in pairs(game.Players:GetPlayers()) do
		player.KillsThatRound.Value = 0
	end
end

function Functions.checkSpawned(player)
	if player.SpawnedInMap.Value == true then
		return true
	elseif player.SpawnedInMap.Value == false then
		return false
	end
end

function Functions.SpawnPlayerValue(player, value)
	player.SpawnedInMap.Value = value
end



function Functions.TeleportPlayer()
	for _, player in pairs(game.Players:GetPlayers()) do
		local SpotsToSpawnIn = {}
		local TheirSpot
		for i, v in pairs(workspace.SpawnPoints["2"]:GetChildren()) do
			table.insert(SpotsToSpawnIn, v)
		end
		for i, v in pairs(SpotsToSpawnIn) do
			print(v)
			local number = SpotsToSpawnIn[math.random(1, #SpotsToSpawnIn)]
			TheirSpot = number
			print(number)
		end
		if player.Character == nil then
			repeat wait() until player.Character ~= nil 
			player.Character.HumanoidRootPart.CFrame = TheirSpot.CFrame
		else
			player.Character.HumanoidRootPart.CFrame = TheirSpot.CFrame
		end
	end
end


function Functions.GetPlayerKnifesAndGiveItToThem()
	for _, player in pairs(game.Players:GetPlayers()) do
	local CurrentKnifeValue = player.CurrentKnifeValue.Value
	local TheirKnife = game.ServerStorage.Knifes:FindFirstChild(CurrentKnifeValue)
	if TheirKnife ~= nil then
		local Cloned = TheirKnife:Clone()
		Cloned.Parent = player.Backpack
	end
	end
end
	
	
function Functions.SetPlayersLeftValue()
	print("s")
	for _, v in pairs(game.Players:GetPlayers()) do
		game.ServerStorage.Values.PlayersLeft.Value = game.ServerStorage.Values.PlayersLeft.Value + 1
		v.inGame.Value = true
	end
end
	
function Functions.KillPlayers()
	for _, v in pairs(game.Players:GetPlayers()) do 
		if v.Character == nil then
			repeat wait() until v.Character ~= nil
			v.Character.HumanoidRootPart.CFrame = CFrame.new(879.31, -14.554, 2603.859)
		else
			v.Character.HumanoidRootPart.CFrame = CFrame.new(879.31, -14.554, 2603.859)
		end
	end
end
	
return Functions

i am aware of the while true loop but that loop is slowed down by waits and the repeat wait.

I’m slightly confused on what you are asking, so I’ll give it a go (sorry if I interpreted your question wrong)

I realize you are aware of the while true, but sadly, that is the reason you are sending so many requests. The

local Functions = require(script.Functions)

and a bit later

Functions.SetPlayersLeftValue() -- This is just an example

Are being fired constantly. Instead, try putting them outside the loop, so they do not fire so many times.

Me just being picky:
You define the variable

local Functions = require(script.Functions)

Twice in the script, once at the beginning, and one inside the while loop. I suggest repeating the one in the while look :wink:

How’d I go about that? The while true loop is slowed down by waiting for the players left to be 1 (handled by a difference script)

1 Like

Also the script is being fired over 893 times…

If it is firing that many times, something is really going wrong. Check every repeat, for loop, and while true loop. Make sure that loop isn’t running too many times - add a lot of prints. Once you find out where exactly your problem lies, you can really dive deeper. If you have any questions, feel free to ask!

The weird part is that the script was fine before I put everything into a module script.

Is the module script really necessary then? It certainly makes the script appear cleaner, but it isn’t that long. . . If I were you, I would revert it to before you added the module script. You can have

local function NameHere()

end

before the while true loop, and just call them. That may be your answer.

That’s what I had but I wanted to try to use a module script

Even not in a module script, it is still looping over 800 times.

Change your while loop to a PlayerAdded.

local matchStarted = false

function lobbyChecker(_) -- I use '_' because you don't need to consider player added or removed unless you want to
   if not matchStarted and #game.Players:GetPlayers() >= 2 then
      matchStarted = true
      -- do the match stuff here
      matchStarted = false
   end
end

game.Players.PlayerAdded:Connect(lobbyChecker)

game.Players.PlayerRemoving:Connect(lobbyChecker)

Thank you for that but it ended being in in another script.

I just added a cooldown to fix it, I was dumb and forgot to check the other script lol.

Be aware that over time, your script will just stop because of Roblox’s default Script Timeout Length. You can’t infinitely keep a loop running unless you change it manually in Studio, but I don’t recommend it.

Okay but

it would give players like 10 knifes

Could you elaborate? I didn’t know that simple scripts like this:

while true do
   print("Hello World")
   wait(3)
end

Can loops with a wait (such as 3 seconds) time out after a while? Wouldn’t that make games unplayable after a while?

Theoretically yes. Technically it’s bad practice, and Roblox Studio opts to place a Script Timeout Length for you by default, but you can easily change it. The reason they place the timer is to avoid you using it in the first place as loops should be finite.

Here’s a good source on managing if you absolutely HAVE to use an infinite loop.

EDIT: More info…

Furthermore, a script with connections would run ONCE and then saved as instances until needed. Even if it is connected forever, the script itself is not running forever. Which is why connections are the way to go since the engine is made for you. An infinite loop is only ever necessary by the engine, not the stuff built on top of it which is what you’re primarily doing when scripting in Roblox. If you need an “Infinite loop” for example you can do so with things such as: In local scripts runService.RenderStepped, runService.Heartbeat:Wait() and such things which are built on top of the running engine.

The first loop is fine.


but the second one isn’t

I’m still a bit confused. Do infinite wait() loops last forever in actual servers / games? Sometimes people afk in games overnight and I don’t understand how those games don’t timeout.

Also:

What would be a good practice if you need an infinite game loop? Something like this:

while true do
   StartGame()
   wait(3)
   GiveItems()
   wait(60)
   EndGame()
   wait(10)
end

So it can run forever, depending, if you add a yields to it where it briefly pauses and such. Now if you want to get really technical, wait() itself is not even a “good” yielding technique. It’s a lot to explain but you can google “Is wait() good yielding roblox” and you’ll get a bunch of results on it.

Good practice is relative though. Like I said depending on what you’re trying to do, there are so many ways to implement it. But connections is definitely the best.

For your last code piece, a good replacement, even though longer would be:

-- we only want to run when players join, so why use infinite loop

game.PlayersAdded:Connect()

-- now we also want to take into account when they leave

game.PlayersRemoving:Connect()

-- now what do they respond to?
function matchLoopHandler()
   -- now this runs when players leave and join... check player count
   -- also add a debounce so that we don't repeatedly run everytime a player joins a leaves
   if game.Players:GetPlayers() > minimumPlayercount and not debounce then
     debounce = true
       -- here we can now do the match loop stuff
      matchLoop()
     debounce = false -- this should only hit once theyre are not sufficient players... I'll show you further below why
   end
end

--- Now the bread and butter of the loop
-- The handler was the "while" part
-- This is what's inside the "while"
function matchLoop()
   GameStart()
   -- whatever here
   GameEnd()
   -- Now, before we return to the main part, we can do the next loop using tail recursion
   if game.Players:GetPlayers() > minimumPlayercount then
       matchLoop() -- loop to the beginning
   end
   -- return all the way and end the "while" loop
end

Clean code without comments:

local debounce = false

function matchLoop()
   RunGame()
   if #game.Players:GetPlayers() > 5 then
      matchLoop()
   end
end

function matchLoopHandler()
   if #game.Players:GetPlayers() > 5 and not debounce then
      debounce = true
      matchLoop()
      debounce = false
   end
end

game.Players.PlayerAdded:Connect (matchLoopHandler)
game.Players.PlayerRemoving:Connect(matchLoopHandler)

Last post about this LOL:

A bonus about using this is if ANYTHING errors, a while loops would break and teh script will stop, making the game unplayable. If a matchLoop errors, it will break that thread, however will reset itself upon the next call of PlayerAdded or PlayerRemoving.