Task.wait() is "faster" when used on the client

In my game, there’s projectiles. On the server, an invisible “real” part is used for handling hit detection, and a remote is fired to every client which creates their own visible “fake” part. Movement for the projectiles, both client and server, is handled like this.

--This is the code for the client-projectile movement
local fakeProjectiles : BasePart = {};
function moveProjectiles()
	for _, fakeProjectile in next, fakeProjectiles do
		fakeProjectile.Position += fakeProjectile.CFrame.LookVector * 5;
	end
end

while true do 
	moveProjectiles();
	task.wait();
end

The problem is that task.wait() does not wait as long as it does on the server, and if you use an FPS unlocker like I do, the projectiles on the client outspeed the actual projectiles by a lot. None of the RunService events seem to change this, as task.wait() is based off of RunService.

1 Like

The RunService events and task.wait both return information regarding how much time has passed (since the last event in the case of RunService or since the call was made in the case of task.wait). This information can be used to move your projectiles at a rate that is invariant from the framerate.

For instance, this modified version of your code would move the projectiles forward at 5 studs-per-second regardless of the framerate.

local fakeProjectiles : BasePart = {};
function moveProjectiles(delta : number)
	for _, fakeProjectile in next, fakeProjectiles do
		fakeProjectile.Position += fakeProjectile.CFrame.LookVector * (5 * delta);
	end
end

game:GetService("RunService").Heartbeat:Connect(moveProjectiles)
3 Likes

As @MysteriousVagabond said, you should use the delta time argument passed with all RunService events, as well as task.wait

local ActualWaitedTime = task.wait(1)
print(ActualWaitedTime)
--Will not print exactly 5, because it's the exact amount of time it waited
--which can have a slight deviation

Also, you could just, use task.wait’s wait argument? That would also mitigate the issue because then you wouldn’t be relying entirely on the client’s framerate, as Roblox will try to wait as close to the wait time as possible instead of just 1 Heartbeat event.

1 Like