Alternatives to "while true do" in my script?

Hey. So I am making an order board, which has several parts inside of it. It moves decals from the highest to lowest numbered part.

This script works, but I dont think using while true do is efficient.

	local next = script.Parent.Parent:FindFirstChild(script.Parent.Name - 1) -- Finds next space
	
	
	--------------------Detects next box for Decal, if false, moves "next"-------------------------
	
	
	while true do -- Loop Script
		
		repeat wait() until
		script.Parent:FindFirstChildOfClass("Decal") ~= nil and -- If current order true and next order nil, continue
			next:FindFirstChildOfClass("Decal") == nil
		
		
		if next:FindFirstChildOfClass("Decal") == nil then -- If next order nil, move current order forward
			wait(2)
			local g = script.Parent:GetChildren()
			
			for i = 1 ,#g do
				if g[i].className == "Decal" then
					repeat wait() until next:FindFirstChildOfClass("Decal") == nil
					g[i].Parent = next
				end
			end
		end
	end

Any solutions?

2 Likes

You could use Runservice to keep it running, for example:

local RunService = game:GetService("Runservice")
RunService.HeartBeat:Connect(function()
--Your code
end)
2 Likes

Hey, the problem with that is, this is a regular script. Runservice seems to be local, which might be an issue.

Also I keep getting this error:
HeartBeat is not a valid member of RunService “Run Service”

You can use RunService and you can use task.wait() instead of wait() because the task library allows u to communicate directly with the game engine’s task schedular.

Here is a link to Task Library if u want to know more about it!

If you can, try to use and somehow implement GetPropertyChangedSignal() instead of while loops in your code.

1 Like

I tried to understand and rewrite the function of your code, and here’s what I came up with:

local next = script.Parent.Parent[tostring(tonumber(script.Parent.Name) - 1)]

script.Parent.ChildAdded:Connect(function(child)
	if child.ClassName ~= "Decal" then return end
	if next:FindFirstChildOfClass("Decal") then return end
	
	wait(2)
	local decals = script.Parent:GetChildren()
	for _,d in ipairs(decals) do
		if d:IsA("Decal") then
			d.Parent = next
		end
	end
end)

I’m not that confident in this code

1 Like

script.Parent.ChildAdded:Connect
Seems like what I was looking for. Lol

Ill try it now.

1 Like

He did the capitalization wrong its Heartbeat

1 Like

For some reason nothing happens.

I think its to do with the function
script.Parent.ChildAdded:Connect(function(child)

I dont really understand why it wouldnt do anything though.
Does the script need to be a Local Script? I dont think using that type would be a good idea though.

I could use GetPropertyChangedSignal() but because the children of the parts would be decals, I dont think I would be able to get it working.

I tested and came up with this script that changes the parent of a Decal to the parts in descending order based on name. Feel free to try it out:

local parts = script.Parent:GetChildren()

table.foreachi(parts, function(i, v)
	if not v:IsA("BasePart") then table.remove(parts, i) end
end)

table.sort(parts, function(a, b)
	return (tonumber(a.Name) or 0) < (tonumber(b.Name) or 0)
end)

for i,p in ipairs(parts) do
	local function onChildAdded(child)
		if not child:IsA("Decal") then return end
		
		local nextPart = parts[i - 1] or parts[#parts]
		if nextPart:FindFirstChildOfClass(child.ClassName) then return end
		
		task.wait(2)
		child.Parent = nextPart
	end
	
	p.ChildAdded:Connect(onChildAdded)
	for _,c in ipairs(p:GetChildren()) do onChildAdded(c) end
end

My explorer:
image

1 Like
local rs = game:GetService('RunService')

c;c=rs.Heartbeat:Connect(function()
  print("drip")
  c:Disconnect() -- break
end)

Hey, thank you.

Although it returned an error with v:IsA("BasePart"). It couldnt find “IsA”

So then I used v.ClassName ~= "Part" and it errors when finding “ClassName”

If you need something that runs a lot but don’t necessarily need a “while true do” as such, and your code revolves around something that is often changing, you’re potentially better off with Instance.Property.Changed:Connect()

If you absolutely must have a while true do, and you will never ever want to escape it, you can cut down on lines/make it cleaner by making it while wait() do instead. Does the same as putting a wait() in a while true do loop, just a lot less characters.

Weird, change the line:

if not v:IsA("BasePart") then table.remove(parts, i) end

to:

if not v or not v.IsA or not v:IsA("BasePart") then table.remove(parts, i) end

Hopefully should fix it.


I do something like:

while true and wait() do

bad but works lol

Hey. Thank you for this. Ive marked it as the solution.

Also another question, how would I stop part number 1 taking the decal back to the beginning?

I’d love to see the order board in action once it’s done.

In my opinion, this sounds extremely complicated next to just doing “while true do”.

Is there any reason that you do not want to use it?

It is. my previous way of doing this works fine. I was just concerned about the while true do line increasing ping ingame.

Ive decided to just use what I had before instead.

Does “task.wait()” do anything different from “wait()”

I don’t think you have to be worried about that, unless you are using an unhealthy amount of remote events and remote functions. Also, you might wanna include a wait of sorts in the while loop.

Okay thanks.

Btw do you know if task.delay or task.wait would be more helpful than wait?