Game Freezing After While Loop's 1st Iteration

I’ve encountered an issue when scripting the server side of an idle loop in my game. The client side is more complex and performing fine, but the server side is causing my game to completely freeze on the first iteration of the while loop (in Studio playtesting and the Roblox Player) and I need to reopen Studio if I want to continue editing the game.

“Iteration 1,” “iteration 2,” and “print 1” (or “print 2;” the issue occurs with waitTime < minWaitTime and waitTime > minWaitTime) each print once on the first iteration of the while loop. Then, the game freezes before “print 3” is reached.

Sorry if any variables are undefined; this is a snippet of a larger script, but the variables are fairly self-explanatory. Feel free to ask if you need any clarification.

The code is as follows.

local minWaitTime = 1

while true do				
	print("iteration 1")
	for i = 1, values.floorCount.Value, 1  do
		print("iteration 2")
		local hp = (values.linearHealthIncrease.Value * (i - 1)) + values.floorOneHealth.Value
		local calcHP = hp / hammerPowerBoost
		local waitTime = calcHP * finalSpeed
		if waitTime < minWaitTime then
			waitTime = minWaitTime
			print("print 1")					
		else
			print("print 2")
		end
		task.wait(waitTime)
		print("print 3")
		
		if values.inRace.Value then
			local winsEarned = values.baseWinsPerFloor.Value * i * refFolder:WaitForChild("boosts"):WaitForChild("winsBoost").Value
			if waitTime < minWaitTime then
				winsEarned = winsEarned * (minWaitTime / waitTime)
			end
			winsVal.Value += winsEarned
			
			local refFolder = plr:WaitForChild("referenceFolder")
			local XP = refFolder:WaitForChild("XP")
			
			local earnedXP = values.XP_perFloor.Value
			if waitTime < minWaitTime then
				winsEarned = earnedXP * (minWaitTime / waitTime)
			end
			XP.Value += earnedXP
			
			highScore = highScore + 1
		else
			break
		end
		
	end
	
	task.wait()

	if values.inRace.Value == false then
		break
	end
	
	-- Handle win
	if #winners <= 3 and not table.find(winners, plr) then
		table.insert(winners, plr)
		local index = table.find(winners, plr)
		remotes.registerWin:FireAllClients(plr, index)
	end
end

If anyone has any idea what could be causing this, please let me know. Thank you in advance!

Correct me if I’m wrong, but you didn’t add any waits? If your gonna use an indefinite loop, which I wouldn’t suggest because it can cause lag sometimes, use

while task.wait() do 
 -- your code
end
1 Like

There is a wait in the main while loop, but even using while task.wait() do, the issue still occurs. Something I’ve realized, though, is that it doesn’t happen all the time. The code never gets to “print 3,” but it doesn’t always freeze :thinking:

The loop is necessary for the game to function, and isn’t indefinite. It breaks when the round ends.

It’s been 3 hours and no one has helped you. Asked ChatGPT to help you. I know this is frowned upon. However, ChatGPT can help with code errors. :sunglasses:

right before the very last end add a task.wait() or instead of running off of while true use runservice on heartbeat or renderstepped

Thanks for the suggestion! The bug seems to have disappeared (maybe I fixed it by accident), but I’ll try this suggestion if it comes back.

1 Like

A little different set up (not much)
The script you posted don’t look like it would have an endless loop problem.
I’m guessing you’re having a problem with the WaitForChild() acting up.
Also never liked using task.wait() … task.wait(0.33) is about as low as I’ll ever go.

local minWaitTime = 1

while values.inRace.Value do
	print("iteration 1")
	for i = 1, values.floorCount.Value do
		print("iteration 2")
		local hp = (values.linearHealthIncrease.Value * (i - 1)) + values.floorOneHealth.Value
		local calcHP = hp / hammerPowerBoost
		local waitTime = math.max(calcHP * finalSpeed, minWaitTime)

		print(waitTime == minWaitTime and "print 1" or "print 2")
		task.wait(waitTime)
		print("print 3")

		if values.inRace.Value then
			local refFolder = plr:WaitForChild("referenceFolder")
			local winsEarned = values.baseWinsPerFloor.Value * i * refFolder.boosts.winsBoost.Value
			local XP = refFolder.XP

			if waitTime == minWaitTime then
				winsEarned *= (minWaitTime / waitTime)
			end

			winsVal.Value += winsEarned
			XP.Value += values.XP_perFloor.Value

			highScore += 1
		else
			break
		end
	end

	task.wait()

	if values.inRace.Value == false then
		break
	end

	if #winners <= 3 and not table.find(winners, plr) then
		table.insert(winners, plr)
		local index = table.find(winners, plr)
		remotes.registerWin:FireAllClients(plr, index)
	end
end

I made some modifications, but I don’t know if it will work, as I can’t test it due to the lack of information about the script!

local minWaitTime = 1;

--// Define refFolder before the loop to avoid re-fetching it multiple times

local refFolder = plr:WaitForChild("referenceFolder");

while true do
	print("iteration 1");

	for i = 1, values.floorCount.Value, 1 do
		print("iteration 2");

		local hp = (values.linearHealthIncrease.Value * (i - 1)) + values.floorOneHealth.Value;
		local calcHP = hp / hammerPowerBoost;
		local waitTime = calcHP * finalSpeed;

		if waitTime < minWaitTime then
			waitTime = minWaitTime;
			print("print 1");
		else
			print("print 2");
		end;

		task.wait(waitTime);
		print("print 3");

		if values.inRace.Value then
			local winsEarned = values.baseWinsPerFloor.Value * i * refFolder:WaitForChild("boosts"):WaitForChild("winsBoost").Value;
			if waitTime < minWaitTime then
				winsEarned = winsEarned * (minWaitTime / waitTime);
			end;
			winsVal.Value += winsEarned;

			local XP = refFolder:WaitForChild("XP");

			local earnedXP = values.XP_perFloor.Value;
			if waitTime < minWaitTime then
				earnedXP = earnedXP * (minWaitTime / waitTime);
			end;

			XP.Value += earnedXP;

			highScore = highScore + 1;
		else
			break;
		end;
	end;

	--// Avoid using task.wait() without arguments to prevent the loop from freezing
	task.wait(0.1); --// Adding a small delay to avoid overloading the loop

	if not values.inRace.Value then
		break;
	end;

	if #winners <= 3 and not table.find(winners, plr) then
		table.insert(winners, plr);
		local index = table.find(winners, plr);
		remotes.registerWin:FireAllClients(plr, index);
	end;
end;