Run Service problem

Hi,
I have a problem with RunService which is running my code more than once even if I have the conditions to execute code once. Do you have any suggestions?

Code Example:

local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder")
local t = {}

run.Heartbeat:Connect(function()

	task.spawn(function()
		
		if #t < #otherFolder then
			table.insert(t, os.time())
		end
	
	end)
	
end)

The otherFolder has one element.

The Heartbeat, as stated in the documentation, fires every frame after the physics simulation has completed.

Since Heartbeat fires every frame, it runs at a variable frequency. This implies that the rate will vary depending on the performance of the machine and doesn’t wait for the end of the calling function to continue. If the game is running at 40 FPS, then Heartbeat will fire 40 times per second, and the step argument will be roughly 1/40th of a second.

In your case, task.spawn serves absolutely no purpose. task.spawn create a new desynchronized thread so it’s just not useful in your situation.

I don’t know why you said, “I have the conditions to execute code once” because you have no conditions that stop the Heartbeat. You just insert some os.time, which amounts to adding 40 numbers per second if your computer runs at 40 frames per second.

If you want to stop the loop when your table is as full as your file, you might to do that:

local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder"):GetChildren() -- Dont forgot the use :GetChildren() to get a table of the content of the instance
local t = {}

local runConnection = nil

runConnection = run.Heartbeat:Connect(function()

		if #t < #otherFolder then
			table.insert(t, os.time())
		else
			runConnection:Disconnect()
			runConnection = nil
		end
	
end)

But that’s really not the best way to do it, I personally prefer to use repeat.

local run = game:GetService("RunService")
local otherFolder = game.Workspace:WaitForChild("otherFolder"):GetChildren() -- Dont forgot the use :GetChildren() to get a table of the content of the instance
local t = {}


repeat
	table.insert(t, os.time())
	run.Heartbeat:Wait()
until (#t >= #otherFolder)

If you have any questions, don’t hesitate to ask me!

2 Likes

I understand that the heartbeat runs that way, but the code should run once, because the table gets one element inserted and then the condition should be false. RunService will run untill I disconnect it, but it shouldn’t run the code inside if the condition is not met. I don’t care about disconnecting the runservice.

Start by using GetChildren on your instance before checking its length. And we dont care about what you dont care, stay polite.

1 Like

Because you’re using task.spawn, it is possible two threads are spawned before the table has actually been updated so the condition is true twice in a row.

Suggestions:

  • print('table size', #t) in task.spawn(function() ... to confirm
  • remove task.spawn
  • create a locking mechanism so the table cannot be updated while another thread is updating it.

That code is an example is not the real code I use. I use GetChildren() for that, but is still running the code 2 times. I am polite! I just said I don’t want to disconnect the runservice, that’s all.

1 Like

No task.spawn has nothing to do with that, as I said previously RunService does not wait for the end of the called function to continue.

1 Like

Yes I disabled the task.spawn(), but my code still run twice even my folder has one element in it.

Yes, it does. If you believe it doesn’t, you don’t understand how task.spawn/threads work.

The fact RunService doesn’t wait is the whole point.

1 Like

You said you don’t care, which is very rude when I’m only trying to help you with a code that isn’t even the one you’re trying to fix. The first code I gave you stops after adding a single element to the table as desired.

1 Like

Dont worry, I understand how it working and I’ve explain why it’s not the issue. Thanks.

1 Like

ha, ok…

Since the code posted doesn’t even run, I’ll assume it’s all just trolling then.

Have a good day.

1 Like

Okay I will not argue on that. I need runservice for a reason. I am checking if os.time() - the time from the table is equal with some other thing and then execute the rest of the code. I have some similar code which runs properly, but here it don’t.

1 Like

Oof

1 Like

try this:
print("#otherFolder", #otherFolder)

I’ll save you the trouble:

It explains everything

That folder is updating at a point in game when I clone something in it and the run service is checking if the number of elements from that folder is greater then the table which has 0 elements and then insert one element and then will wont run because the condition is false. And then I am checking if the os.time() - the time from the table is equal with another value stored in profile service and when that is met the code inside will run once and then the time is removed from the table and redoing the cycle until I get my other conditions etc. But the problem is that the code is running two times in all of my if statements.

1 Like

Attempt to get lenght of a Instance value

He need to do

local otherFolder = game.Workspace:WaitForChild("otherFolder"):GetChildren() 

And not

local otherFolder = game.Workspace:WaitForChild("otherFolder")

You cannot get the length of an instance…

1 Like

Yep, agreed. Which is why I said the original code posted is broken.

1 Like

Yes I have GetChildren() other ways the code will error. I just forget to add it in the example.

1 Like