Custom wait - the best solution to yielding!

The line of code is in the command bar

Uuh. RunService events shouldn’t fire on command bar…

You can use it just fine inside normal scripts.

I believe you can use task.wait instead of wait on the command bar though.

1 Like

Hi, I have a procedural map generation system that although is blazing fast, has a woping 12 waits in the main script to keep it from exhaust timeout (don’t remember the exact name) Although I was aware this was not ideal, I was not aware it was that bad. so I want to thanks you for 3 things:

  1. Educating us in effective code design and construction
  2. Making this module which looks AMAZING!
  3. Making the code open source
1 Like

So is ROBLOX task.wait() better or this module?

1 Like

yea I am curious about this now

@D0RYU @nakata1609

1 Like

What I mean is which one is more accurate

They should be similar, this should give you a more “accurate” yield time, but they should take basically the same amount of time.

If you’re messing with things the user might see like UI things or something, then go with … well neither I think.

What this function is made for is really being friendly to the thread scheduler, but apparently that’s fixed? so…

If you want something for UI use or something, things that depend on framerate, something the user sees, then you might wanna look into my little fork in my github

If you want to use something that depends on frame rate you should be using BindToRenderStepped, as pointed out by me above. RenderStepped waits for each callback to finish anyway, so it’s not as if a custom task scheduler for RenderStepped will change anything.

This module or task.wait? better for accuracy?

4 Likes

This module is still ever-so-slightly more accurate, as it doesn’t need to converse back and forth between the Lua and C APIs unlike task.wait.
Sorry for late response, I don’t usually check up on this thread.

1 Like

Thanks for this module. I did some tests myself and found that @StrategicPlayZ’s wait module is ever so slightly better.

1 Like

Made a pull request which replaces the old junk coroutine.resume in favour of the new and better task.spawn. Ideally this module should be using the new task library.

1 Like

Thanks, I merged the commit. Also made additional changes to casing, variable names, and additional localization of table.insert.

My code for one of my modules seems to yield permemently and I have no idea why.

Code Source
local FuncE = function(CPM:number|()->(number),keepCache:boolean)
		local sV = {}
		local function pCPM():number
			if typeof(CPM) == 'function' then
				return CPM()
			else
				return CPM
			end
		end
		while true do
		data.OnYield:Connect(function()
			data['OnResume'].Event:Wait()
		end)
			if #data['_D']['Sched']>0 then
			sV[3],sV[4]=pcall(data['_D']['Sched'][1]['Func'],table.unpack(data['_D']['Sched'][1]['Args'])) -- [pcall's the function with the given arguements]
				if sV[3] then data['OnUpdate']:Fire() else data['OnError']:Fire(sV[4]) end -- [Fires the 'error' event if an error is returned]
			if keepCache then table.insert(data['_C'],data['_D']['Sched'][1]) end -- [Keeps cache]
			data['_D']['Sched'][1] = nil -- [Cleares the called schedule]
			if #data['_D']['Sched'] == 0 then -- [Check if there are any functions in the sequence]
				sV[1] = os.clock()
				data['OnAddedSched']:Wait()
				sV[2] = os.clock();if sV[2]-sV[1] < CPM then cwait(sV[2]-sV[1]) end -- [Delays if needed to not exceed CPM]
			end
			end
			sV[5] = 60/pCPM()
			cwait(sV[5]) 
		end
	end	

The function is run in a coroutine. Although it still would infinitely yield w/ or w/o a coroutine.

@PysephDEV still having an issue with this infinitely yielding in loops w/ or w/o coroutines.

Please provide a minimal repro, it’s really hard to make out what’s going on with all that code.

cwait(), which is your custom wait function, is called with a number after the code for the loop has been done, but it would yield infinitely in that loop

Here's the code again but with relevant parts only
local FuncE = function(CPM:number|(number)->(number),keepCache:boolean)
		local function pCPM():number
			if typeof(CPM) == 'function' then
				return 60/(sV[13]-(OsClock()-sV[12]))	
			else
				return 60/CPM
			end
		end
                 --main code here
	        cwait(pCPM())
		end
	end	

This is still very convoluted and bloated with behavior I’m unaware of. sV is not defined, CPM is a variable and not a constant, pCPM should be removed and replaced with a constant variable, etc. There can be a lot of factors at play here, such as (sV[13]-(OsClock()-sV[12])) being lesser than 1, or perhaps approaching 0, which would lead to the yield being seemingly “infinite”, when in reality it simply yields for absurd periods of time.

sV is just a table for variables that aren’t in much use to have their own local variable. sV[13]=()sClock()sV[12])) will always be above 0. And for the inputs it was a number anyways and so it should be fine.

pCPM is for processing CPM, which can either be a function that takes in a number then outputs it, or just a number for the wait.