Leaf Color Change

Hi. Im trying to make climate in my game. It will change leaf color every hour(in world time), but im wondering how to make thats more effecient, because i have 200+ models of leaves

I think you should be fine, if anything you could break it up over time. like 15 mins before change 25% of it and so on, so there isnt a big lag spike at once. Do you plan on changing it on the server or client, i would suggest client. and have the server keep a reference on the current climate.

Thank you, i need somehow to keep the variable of current climate, should i keep in on server or module script?

1 Like

I’m unsure if you use one script for all the leaves already, or if you add a script to each Object/thing you want to have that logic. For organizational reasons, I’d recommend one script controlling all of them using Tags for all the objects you want to have that logic.

For optimization, a separate script, maybe a Module script, controls all the timing logic. Then, an Event that updates the main script for the color behavior. That way, you don’t have a bunch of timers; the leaves all changed at the same time based on that one timer.

Don’t do it all at the same time. Maybe add a .05 second interval between tree changes.

1 Like

I will try to do it with tags, thank you for wonderful idea

1 Like

If the climate impacts gameplay in a way that the player could have an advantage by exploiting/changing it, then keep it on the server.

CollectionService could help you out, maybe?

What I’d do is create a module that intakes parts and adds them to a queue, and every x resolve a certain amount of the queued parts.

Here’s a short module I wrote with comments, please take the time to read them:

(FYI I didn’t test this so it may have a bug)


--!strict

local MAXIMUM_CHANGED_PER_UPDATE = 3

local RunService = game:GetService("RunService")

local Module = {}
local PendingChanges = {} :: {[BasePart]: Color3}
local UpdateConnection: RBXScriptConnection?

local function Update(IgnoreMaxChanged: boolean?)
	local Counter = 0

	for Part, Color in PendingChanges do
		Part.Color = Color
		PendingChanges[Part] = nil
		
		-- If given a max amount changed, check if we've reached it and stop if so
		Counter += 1
		if (IgnoreMaxChanged ~= true) and Counter == MAXIMUM_CHANGED_PER_UPDATE then
			return
		end
	end
	
	-- Weve finished looping through the pending parts!
	if UpdateConnection then
		UpdateConnection:Disconnect()
		UpdateConnection = nil
	end
end

function Module.QueueChange(Part: BasePart, Color: Color3)
	PendingChanges[Part] = Color

	if not UpdateConnection then
		UpdateConnection = RunService.Heartbeat:Connect(Update)
	end
end

function Module.ClearQueue(ResolveAllPending: boolean?)
	if ResolveAllPending then
		Update(true) -- 'true' to tell it to ignore the max changed check
	else
		table.clear(PendingChanges)
	end
end

I would suggest keeping it in a module script this way you can reference it where ever you need

ClimateData.lua (Module Script)
return {
 Season = "Summer",
 Temperature = 80,
}

Then you can also do

-- Some Script
local ClimateData = require(path.to.ClimateData)

print(ClimateData.Season)
ClimateData.Season = "Winter"
ClimateData.Temperature = 20
print(ClimateData)