Custom Dynamic Cloud System

  1. What do you want to achieve?
    I currently have a very simple cloud system, which spawns in parts and moves them across the sky using tweens. I want to achieve dynamic weather effects, such as thunderstorms, cloudiness, ect. And also to make the clouds follow the player.

  2. What is the issue?
    The problems I am facing is that, since I am using tweens, they don’t really follow the player easily and I am unsure of how I can achieve dynamically changing weather that wouldn’t result in lag spikes, since I have anywhere from around 100-200 clouds.

  3. What solutions have you tried so far?
    I tried rewriting the cloud system to make it local, which while did improve performance server sided, I don’t want weaker devices to struggle with these clouds, since the game is supposed to be simple.

Show us your code otherwise we cannot help you. Also please don’t expect to be given code.

I believe there is cloud systems that are game wide or I think there is one that has these regions. I don’t have the links to the and forgot what it was called but I am sure someone can correct me.

The code isn’t really that complicated, since like I said, it just spawns parts in and moves them using tweens:

function generate_cloud(offset)
	local cloud_time = 60-60*offset
	local cloud_movement_info = TweenInfo.new(cloud_time,Enum.EasingStyle.Linear)

	local new_cloud = nil

	if #freed_clouds > 0 then
		new_cloud = freed_clouds[1]
		table.remove(freed_clouds,1)
	else
		new_cloud = Instance.new("Part",cloud_folder)
		new_cloud.BrickColor = BrickColor.new("Institutional white")
		new_cloud.CanCollide = false
		new_cloud.Anchored = true
		new_cloud.CastShadow = false
		new_cloud.Transparency = 1
	end
	new_cloud.Size = Vector3.new(40*get_random_scale(0.1),20*get_random_scale(0.1),40*get_random_scale(0.1))
	new_cloud.Position = Vector3.new(-cloud_offset+(cloud_offset*2)*offset,cloud_height,math.random(-cloud_offset,cloud_offset))

	local fade_in = tween_service:Create(new_cloud,cloud_transparency_info,{Transparency = 0.5})
	local move = tween_service:Create(new_cloud,cloud_movement_info,{Position = Vector3.new(cloud_offset,cloud_height,new_cloud.Position.Z)})
	local fade_out = tween_service:Create(new_cloud,cloud_transparency_info,{Transparency = 1})

	fade_in:Play()
	move:Play()
	task.wait(cloud_time-5)
	fade_out:Play()
	task.wait(5)
	move:Pause()

	fade_in:Destroy()
	move:Destroy()
	fade_out:Destroy()
	table.insert(freed_clouds,new_cloud)

	spawn(function()
		generate_cloud(math.random()*0.1)
	end)
end

You can still use tweens just get the target players position, the clouds current position and then calculate the magnitude. After getting the magnitude add it to whatever position you need to OR you can get the players CFrame and tween the cloud to that CFrame. ofc exclude any data you don’t need.

Some format advice as your code looks bad:

  1. Space your code logic out like any arguments, example: Vector3.new(x, y, z) looks better
  2. Use task instead of things like spawn or wait, task.spawn() is much better in terms of performance.

The suggestion of tweens and also try with the guy said above using more task instead of wait

function generate_cloud(offset)
    local cloud_time = 60 - 60 * offset
    local new_cloud = nil

    if #freed_clouds > 0 then
        new_cloud = table.remove(freed_clouds, 1)
    else
        new_cloud = Instance.new("Part", cloud_folder)
        new_cloud.BrickColor = BrickColor.new("Institutional white")
        new_cloud.Anchored = true
        new_cloud.CanCollide = false
        new_cloud.CastShadow = false
        new_cloud.Transparency = 1
    end

    new_cloud.Size = Vector3.new(40 * get_random_scale(0.1), 20 * get_random_scale(0.1), 40 * get_random_scale(0.1))
    new_cloud.Position = Vector3.new(-cloud_offset + (cloud_offset * 2) * offset, cloud_height, math.random(-cloud_offset, cloud_offset))

    local fade_in = tween_service:Create(new_cloud, cloud_transparency_info, { Transparency = 0.5 })
    local move = tween_service:Create(new_cloud, cloud_movement_info, { Position = Vector3.new(cloud_offset, cloud_height, new_cloud.Position.Z) })
    local fade_out = tween_service:Create(new_cloud, cloud_transparency_info, { Transparency = 1 })

    fade_in:Play()
    move:Play()
    task.wait(cloud_time - 5)
    fade_out:Play()
    task.wait(5)
    move:Pause()

    fade_in:Destroy()
    move:Destroy()
    fade_out:Destroy()

    table.insert(freed_clouds, new_cloud)

    task.spawn(function()
        generate_cloud(math.random() * 0.1)
    end)
end

function update_cloud_position(cloud, player)
    local player_position = player.Character and player.Character.PrimaryPart.Position or Vector3.new(0, 0, 0)
    local cloud_position = cloud.Position
    local magnitude = (player_position - cloud_position).magnitude

    cloud.Position = Vector3.new(player_position.X + magnitude, cloud_position.Y, player_position.Z + magnitude)
end