What is the most efficient way to check if (condition) has happened?

Is there an overall most efficient way to keep checking if a condition has happened?

I know two methods for achieving this:

while true do
    wait()
	if condition then
		--code
	end
end

or

local RunService = game:GetService("RunService")

RunService.RenderStepped:Connect(function()
	if condition then
		--code
	end
end)

So my main question is asking, are these the only two ways to check something constantly? If not then what are the other ways, and which would be the most efficient?

something similar to Unity3D’s Update method if you are familiar with that

1 Like

You can use an Event if there is any for what you are doing (Script Signal / Connections)

Examples;

CharacterAdded
PlayerAdded

And you can use :Wait or Connect it to a function



1 Like

My Solution


I completely understand what you are asking. I have also found my self in this situation many times where I need to check if a variable defined within my code has changed throughout time.

For example: If sprint energy has reduced to a value below 10

I’ve looked into it a lot and the best solution I have found is instead of using a variable defined in your code, change the variable to a value (like a StringValue) parented to your script, and set the variable to the value of that (string)value.

Example:

Old Code:

local sprintEnergy = 100 -- 100% spring energy

while true do
    wait()
	if sprintEnergy < 10 then
		--code
	end
end

New Code:

local sprintEnergyValue = Instance.new("IntValue", script)
sprintEnergyValue.Value = 100

sprintEnergyValue.Changed:Connect(function()
if sprintEnergy.Value < 10 then
-- Code
end
end)

Hope that helped! This is my solution every time I have this problem.

12 Likes

The solution Sentro gave looks rather haxy and isn’t the way I would go about doing it since I (and many other devs) try to not use any type of Value-Instances in our work. The other issue is if there are too many Instances being formed inside of a script that aren’t destroyed to allow the garbagecollector to take care of the rest, that’ll quickly eat up your memory-resources and will result in a server eventually lagging out then crashing.

To answer the actual question, this is my first method I use to wait until a condition changes since it’ll easily allow for more code to follow after it and can easily be reused without have to spawn a function:
I prefer using Heartbeat instead of RenderStepped since Heartbeat fires at the end of every frame which is further elaborated here a bit: Heartbeat, RenderStepped and Stepped Differences

local RunService = game:GetService("RunService")
local Connection

Connection = RunService.Heartbeat:Connect(function()
    if condition then
        --Code
        Connection:Disconnect() --Makes the loop stop if you want it to
    end
end)

This is the other way I go about doing it make the entire script stops until that condition has happened

repeat wait() --[[Other code here if you want ]] until condition
-- Rest of code

I try to avoid using while true do wait() print("IHazCodeHere") end since that means I’ll have to use break someplace to end the loop yet many still do it and their code runs fine. It simply comes down to what you are trying to achieve when checking a certain condition and where your variables that go with the condition are located.

Edit: If you need any help with making loops that check for a condition just send me a DM and I’ll help you figure out probably which one is the best to use.

14 Likes
while true do
    wait()
    if condition then
        -- Code
    end
end

Why would you yield pointlessly at the beginning of an iteration and why would you check a condition this way? The conditional statement of a while loop exists, which is to allow the loop to resume iterations until the condition has been met. Use that condition.

while condition do
    -- Your code
    wait()
end
2 Likes

I personally feel like sentro’s idea heads in a more correct direction than NKM9’s. Making a check 30 or 60 times a second uses more cpu resources. I would hook up a function to a (remote or bindable event) or module script if the value is needed outside of the script. Otherwise I would do everything inside the script by using passthroughs.

local condition;

function Check()
    if condition then --check condition
        -- Code
    end
end

function UpdateTheConditionalItem(NewValue)
    condition = NewValue
    Check()
end

Using UpdateTheConditionalItem(NewValue) we can check the value to see if it meets the condition every time it is updated. You can also hook this up in a module and require that module to move the condition between multiple scripts.

1 Like

To answer your main question, those are more or less the only ways to check a condition constantly. Other permutations exist (using repeat instead of while, other events, etc), but those are the two basic models.

I suggest against doing either of them though. A better solution would be to use events and wait until they fire to run whatever code you want to run under that condition. It’s more elegant and wastes less time and memory.

As for which is most efficient, I’d like to make a note. You should absolutely avoid using wait() (with no arguments) whenever possible since the time it waits is actually variable. There’s a nice thread by Kampfkarren on that subject here. As a result, the better option of the two provided in your OP would be to use RenderStepped.

2 Likes