Shorter Than task.wait(0)

Situation:

I am trying to make a simulator-like game, where you have to collect bricks.

There are also upgrades that make the bricks spawn faster!

Now, the max upgrade basically promises a player a brick-spawn-cooldown of 0!

Using task.wait(0), however, will not achieve a near-instant spawn-rate.

What I have tried (and how my attempts failed):

Using RunService.Stepped:Connect(functionNameHere)
→ Failed because it wouldn’t let me disconnect it

Using RunService:BindToRenderStep(functionNameHere)
→ Failed because it would only run once

i also tried some little fixes to the failed things above but it still wouldn’t work!

Base script (I added some comments to make it more understandable):

local chances = require(script.Chances)
local upg = require(game:GetService("ServerScriptService").Upgrades)

while true do
	
	for i, v in pairs(game:GetService("Players"):GetPlayers()) do
		--obvious one here: v = the player
		if v ~= nil then -- making sure the player exists 
		
			local onCD = v:WaitForChild("OnCD") -- BoolValue, parented to the player, that checks if the spawning is on cooldown
			
			if onCD.Value == false then
				
				onCD.Value = true
				--now del: This is short for delay, the delay is stored in a module script. This script grabs the delay based of the player's (v's) SpawnRate Level
				local del = upg.getUpgrade("SpawnBrickCooldown")[v:WaitForChild("SpawnBrickCooldown").Value][1]
			
				task.delay(del, function() -- task.delay so that there arent any complications in multiplayer (eg: if 1 player has a 5 sec cooldown, it would pause the spawning for everybody for 5 secs, fixed with task.delay)
					
					local brick = chances.pickRandomBrick() -- picks a random bricktype using the modulescript

					script.SpawnBrick:Fire(v, brick) -- makes another script actually place the brick
					
					onCD.Value = false -- sets OnCooldown to false so that another brick may spawn
					
				end)
				
			end
			
		end
		
	end
	
	task.wait(0.0001) -- anti crash cus of while loop

end

Thanks for your help in advance!

1 Like

Cant you just do task.wait() and thats it?

4 Likes

Spawn 2+ bricks on tick. Not one.
It’s impossible to be faster than calculation rate of pc.

3 Likes

remove the task.wait when you dont need a delay

1 Like

That wouldnt make it better, however, this gave me an idea!

If the delay is 0, ill just completely remove the task.wait

(just like @commitblue just said)

just tried it, doesnt work (to be precise, i added a condition that checks if the delay == 0! if it isnt, it uses task.delay! if it is it doesnt use task.delay

Try renderstepped.Stepped:Wait()

1 Like

RunService.RenderStepped:Wait()

1 Like

well, for one thing i did already try that

but i tried using it again now (as the anti-while-loop-crash, instead of task.wait(0.0001)) and it still didnt work

also my script is in serverScriptService; renderstepped wont work, i used Stepped instead

Also, just to clarify, the script worked, but not at the intended speeds.

local chances = require(script.Chances)
local RunService = game:GetService("RunService")
local upg = require(game:GetService("ServerScriptService").Upgrades)

RunService.Stepped:Connect(function()
	for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
		local onCD = player:FindFirstChild("OnCD")
		if onCD and not onCD.Value then
			onCD.Value = true
			
			local cooldown = upg.getUpgrade("SpawnBrickCooldown")
			[player:WaitForChild("SpawnBrickCooldown").Value][1]
			
			local brick = chances.pickRandomBrick()
			script.SpawnBrick:Fire(player, brick)
			task.delay(cooldown, function() onCD.Value = false end)
		end
	end
end)

fast and solid.

1 Like

awesome as a starting point, but still not the solution. When i connect the spawning to RunS.Stepped its WAAAY faster. so, the result i seek is achievable, but still far of

also, there is something i wanted to add here: I already made a working script: But heres the problem:

In my game there is a kinda of rebirth? that resets ur level. My script couldnt disconnect the rs.Stepped:Connect connection anymore (idk why), which led to basically level 0 people to get the instant brick respawn

make bricks spawn immediately after player collects bricks (like on same frame)

example:

playerCollectBricks() -- notice how there's no task.wait() in between also no cooldown?
spawnNewBricks()
1 Like

task.wait() resumes the thread on the next Heartbeat.

This function here

local function sleep(n)
	local now = os.clock()
	while os.clock() < (now + n) do end
end

…does not use the task scheduler. It is however still handled by the engine, so how low it can go depends on the engine.

1 Like

smart as heell boi
tysm EEEEEEEEEEEEEEEEEEE

(just realized you provided code)

here’s what i’d do:

local chances = require(script.Chances)
local upg = require(game:GetService("ServerScriptService").Upgrades)

while true do
	
	for i, v in pairs(game:GetService("Players"):GetPlayers()) do
		--obvious one here: v = the player
		if v ~= nil then -- making sure the player exists 
		
			local onCD = v:WaitForChild("OnCD") -- BoolValue, parented to the player, that checks if the spawning is on cooldown
			
			if onCD.Value == false then
				
				onCD.Value = true
				--now del: This is short for delay, the delay is stored in a module script. This script grabs the delay based of the player's (v's) SpawnRate Level
				local del = upg.getUpgrade("SpawnBrickCooldown")[v:WaitForChild("SpawnBrickCooldown").Value][1]
			
				task.spawn(function() -- instead of task.delay, use task.spawn to have more control
					if del > 0 then
                        task.wait(del) -- if delay is above zero, wait, if not, don't wait.
                    end

					local brick = chances.pickRandomBrick() -- picks a random bricktype using the modulescript

					script.SpawnBrick:Fire(v, brick) -- makes another script actually place the brick
					
					onCD.Value = false -- sets OnCooldown to false so that another brick may spawn
					
				end)
				
			end
			
		end
		
	end
	
	task.wait() -- task.wait() can have nil interval, equivalent to one frame.

end
1 Like

…or this also works if you wanted t === 0.

1 Like

i apologize for providing pseudocode despite the fact that you provided code already

1 Like

Instead of using a while true do loop
Use this loop

local RunService = game:GetService("RunService")

RunService.Heartbeat:Connect(function()

-- Add loop code here

end)

This will run every frame

1 Like