Hello.
I am making a simple bullet controller, where the bullet moves by a certain amount with delays.
I am trying to utilize parallel luau, but I’ve encountered some problems, the script rate is extremely high(>100) even though im using task.wait(1) inside the loops.
Heres the script:
repeat
local TargetCFrame = Bullet.Object.CFrame*CFrame.new(-Bullet.Speed*10,0,0)
task.synchronize()
game.TweenService:Create(Bullet.Object,TweenInfo.new(1,Enum.EasingStyle.Linear),{CFrame = TargetCFrame}):Play()
task.desynchronize()
task.wait(1)
until (Bullet.Object.Position-Vector3.zero).Magnitude > 100
I am very new to this parallel luau stuff, so do tell me if im doing something wrong. Help would be much appreciated.
It’s due to you using parralell luau. Parralell luau ignores task.wait() you could say. It does not run with the normal thread, but rather with the thread, so unless you have a task.wait() inside the thread, its gonna just run really fast.
By using task.spawn(), the bullet movement will be executed in a separate task, which can help improve the script rate. The task.wait(1) will still introduce a delay between each bullet movement.
task.defer uses a function on the next heartbeat, so thats the reason for sure. Don’t use any task function with the exeption of task.wait(), or just don’t use parallel. If you want a low rate, serial (aka the default) is 60/s max. Parallel does have its upsides though, so I recommend use it, when possible, as it really does not hurt the script as it’s running alongside.
local RunService = game:GetService("RunService")
local function moveBullet()
local bullet = Bullet.Object
local targetCFrame = bullet.CFrame * CFrame.new(-Bullet.Speed * 10, 0, 0)
game.TweenService:Create(bullet, TweenInfo.new(1, Enum.EasingStyle.Linear), { CFrame = targetCFrame }):Play()
end
local function checkDistance()
local distance = (Bullet.Object.Position - Vector3.zero).Magnitude
return distance > 100
end
RunService.Heartbeat:Connect(function()
if checkDistance() then
moveBullet()
end
end)
Use the RunService.Heartbeat event to continuously check the distance and move the bullet if necessary. The moveBullet() function handles the bullet movement using TweenService, and the checkDistance() function determines whether the bullet should continue moving.
Consider using the microprofiler instead to measure performance.
Script activity is a quick indicator, but doesnt tell the whole story and had some bugs in the past.
Script rate however doesnt really tell much if it uses a renderstep loop it will be really high but the performance cost may thr low such as some camera CFraming.
I’m unsure why but this surpasses the 60/s rate limit by a lot even though im pretty sure i didnt use any parallel stuff.
Script performance is 49% or so, very high compared to the parallel one.
Because a loop without wait time run as fast as possible, generaly at (0.001) to (0.0001) something like that, and most of the time it make the game crash.
Every Repeat Until and While Do loops must have a task.wait() to limit the rate at your FPS count, the minimum being 30/s (0.03)
Any script activity shouldn’t be above 3%, and the rate of a script doesn’t matter as long as your script is optimized… if your script activity really is at 49% then there’s a huge performance issue.
If the overall code is the same then the performances doesn’t change in reality, you’re just moving a part of the unoptimized code to an another thread so it isn’t shown as a part of the script.
Also, i don’t understand why do you want to run a Tween into a new thread while it isn’t even yielding the script at all, it is not needed.
From what i saw a lot of times on the forum, it is not, that’s why you need to use task.wait so it connect the loop to heartbeat, same as runservice.Heartbeat
7% is still too much ^^
This come only from this single loop ?
Doing something like this should reduce it
local TweenService = game:GetService("TweenService")
local Info = TweenInfo.new(1, Enum.EasingStyle.Linear)
local Object = Bullet.Object
local TargetCFrame = nil
repeat
TargetCFrame = Object.CFrame * CFrame.new(-Bullet.Speed*10, 0, 0)
TweenService:Create(Object, Info, {CFrame = TargetCFrame}):Play()
task.wait(0.1)
until (Object.Position - Vector3.zero).Magnitude > 100
Are you sure that this high percentage is only caused by this loop?
You do a different thread loop for each bullet? Each bullet has its own loop?
It is weird because, i also made a infinite loop that run 10/s in the game i’m working on, and this loop is handling much more things than you including +20 different tweens, and the script never go above 1% so idk.
Oh yeah, so that’s why…
You should try to use a single loop and CollectionService like this:
--[[ Roblox Services ]]--
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")
local BulletInfo = TweenInfo.new(1, Enum.EasingStyle.Linear)
--[[ Main Tables ]]--
local TableBullet = {}
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--[[ Local Functions ]]--
local function TweenBullet(Bullet)
if (Bullet.Object.Position-Vector3.zero).Magnitude > 100 then
table.remove(TableBullet, TableBullet[Bullet])
else
TweenService:Create(Bullet.Object, BulletInfo, {CFrame = Bullet.Object.CFrame * CFrame.new(-Bullet.Speed*10,0,0)}):Play()
end
end
--------------------------------------------------------------------------
--------------------------------------------------------------------------
--[[ Connections Setup ]]--
CollectionService:GetInstanceAddedSignal("Bullet"):Connect(function(Bullet)
if Bullet:FindFirstAncestorWhichIsA("Workspace") then
table.insert(TableBullet, Bullet)
end
end)
CollectionService:GetInstanceRemovedSignal("Bullet"):Connect(function(Bullet)
table.remove(TableBullet, TableBullet[Bullet])
end)
--[[ Loop Setup ]]--
while task.wait(0.1) do
for _, Bullet in pairs(TableBullet) do
TweenBullet(Bullet)
end
end
Iterating through thousands objects may lag, but you can split it to one loop and one table per player/weapon which still is better than a new thread loop for every single bullet… then it should reduce the ressources taken by half and down the script rate to 0.1s * number of players.