Laggy issue on rainy system

Im trying to make quality weather system (rainy) which required raycasting on the ground for the water splash effect inside a runservice loop

  • This is an part of my code that using runservice :
		local _in = _inCFX:Clone()
		_in.Name = weather.Confg
		table.insert(followers, _in)
		_in.Parent = workspace.Visuals

                
		if idk then
			idk:Disconnect()
		end
		
		idk = rS.Heartbeat:Connect(function()
			local drp = script.Drop:Clone()
			table.insert(consution, drp)
			db:AddItem(drp, 5)
			drp.Parent = _in
			drp.Anchored = true
			drp.CFrame = _in.CFrame
			drp.CFrame *= CFrame.new(
				math.random(-zone, zone),
				0,
				math.random(-zone, zone))

			local max = 1000
			local params = RaycastParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			params.FilterDescendantsInstances = bC:GetRaycastAvoid({p.Character:GetDescendants(), p.Character})
			local result = workspace:Raycast(drp.Position, drp.Position - (drp.Position - Vector3.new(0, -max, 0)), params)
			if result and result.Instance then
				drp.Position = result.Position
				drp.SPLASH:Emit(20)
				task.wait(1)
				if drp then
					drp:Destroy()
				end
			else
				drp:Destroy()
			end
			task.wait(.1)
		end)
  • ~ i have other codes which using runservice with raycasting without being laggy which make me confuses about this one

  • ! is there anyway to improve this code?

Also, any help is appreciated!

2 Likes

Raycasting isnt the problem here I believe

You shouldnt clone your raindrop and destroy it each time, since this causes lag, instead you should pool them:

local replicatedStorage = game:GetService("ReplicatedStorage")

local pool = replicatedStorage:WaitForChild("pool")
local part = replicatedStorage:WaitForChild("part")

while task.wait() do
local newPart = pool:GetChildren()[1] or part:Clone()
--Code
task.wait(5)
newPart.Parent = pool
end

I can barely read your code please use readable variable names next time, thank you

you also dont have a proper debounce, hartbeat/ renderstep doesnt wait when you use task.wait():

local runService = game:GetService("RunSurvice")

local debounce = false
local updateTime = 0

runService.Hartbeat:Connect(function()
if debounce then return end
debounce = true
--Code
task.wait(updateTime)
debounce = false
end)
1 Like

It’s better to run all the logic for the rain system on the client rather than the server. Less intensive on the server, just use a Remote Event to fire all clients whenever the weather system needs to make it rain. Running it on the client allows you to use RenderStepped rather than the server’s Heartbeat.

1 Like

is it really on the server? i thought you can use hartbeat on the client aswell

You can use Heartbeat on the client as well as far as I’m aware. But you can’t use RenderStepped on the server, and there’s no point in using Heartbeat if you’re on the client as you have access to RenderStepped and Stepped

Here is what I would do (dont copy this i made it on mobile):
Instructions:

  • Local script
  • Folder in replicatedstorage called pool
local _in = _inCFX:Clone()
_in.Name = weather.Confg
table.insert(followers, _in)
_in.Parent = workspace.Visuals

local pool = replicatedStorage:WaitForChild("pool")
local drop = script.Drop
if connection then connection:Disconnect()
end	

connection = runService.RenderStepped:Connect(function()
if debounce then return end
debounce = true
local newDrop = pool:GetChilderen()[1] or drop:Clone()
newDrop.Parent = _in
newDrop.Anchored = true
newDrop.CFrame = _in.CFrame
newDrop.CFrame *= CFrame.new(
math.random(-zone, zone),
0,
math.random(-zone, zone))

local max = 1000
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = bC:GetRaycastAvoid({p.Character:GetDescendants(), p.Character})
local result = workspace:Raycast(drp.Position, drp.Position - (drp.Position - Vector3.new(0, -max, 0)), params)
if result and result.Instance then
newDrop.Position = result.Position
newDrop.SPLASH:Emit(20)
task.wait(1)
end
newDrop.Parent = pool
task.wait(0.1)
debounce = false
end
1 Like

this code is client based tho

Btw tysm for replying!

you reminded me that the runservice wont stop with task.wait :sob:

also the some of names are random( the remaining are abbreviated )

  • I will try to improve the script through your suggestions. Tysm for your help
1 Like

i thought the heartbeat will runs faster than others on the client side :skull:

1 Like
  • update for the script

after changing the script as per your suggestion, this is the code after changed :

		local index = 0
		idk = rS.RenderStepped:Connect(function()
			if not deb and index < maximumDrp then -- maximumDrp  : maximum amount of drops
				deb = true -- debounce
				if not hrp then
					hrp = p.Character:FindFirstChild("HumanoidRootPart")
				end
				
				index += 1
				local drp
				if not consution[index] then
					drp = script.Drop:Clone()
					drp.Parent = _in
					drp.Anchored = true
					consution[index] = drp
				else
					drp = consution[index]
				end
				drp.CFrame = _in.CFrame
				drp.CFrame *= CFrame.new(
					math.random(-zone, zone),
					0,
					math.random(-zone, zone))

				local max = 1000
				local params = RaycastParams.new()
				params.FilterType = Enum.RaycastFilterType.Exclude
				params.FilterDescendantsInstances = bC:GetRaycastAvoid({p.Character:GetDescendants(), p.Character})
				local result = workspace:Raycast(drp.Position, drp.Position - (drp.Position - Vector3.new(0, -max, 0)), params)
				if result and result.Instance then
					drp.Position = result.Position
					if (drp.Position - p.Character:FindFirstChild("HumanoidRootPart").Position).Magnitude <= 1.2*zone then 
						drp.SPLASH:Emit(20)
						task.delay(1, function()
							if drp then
								--drp:Destroy()
								index -= 1
							end
						end)
					else
						--drp:Destroy()
						index -= 1
					end
				else
					--drp:Destroy()
					index -= 1
				end
				task.wait(.05)
				deb = false
			end
		end)

now its running perfectly without lagging

Please let me know if anything needs to change

Looks way better, but for readability I have one more tip, dont use so many nested statements.
So instead of:

if debounce == false and count < maxCount then
--Code
end

You should do:

if debounce or count >= maxCount then return end
--Code

This doesnt have anything to do with performance but makes your code easier to understand ans more readable.
Glad I could help btw

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.