How do I make this ocean animation script optimized?

This script is a simple while loop in my game. It changes the texture of the ocean every fraction of a second to make it look like it is flowing. However, I’ve heard on certain devices, particularly mobile, that there are lag spikes, and affected users have said that the spikes were attributed to the water (they said when they looked away from the water, there was no lag)

Here’s the script:

while true do
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078195"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078221"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078254"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078304"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078342"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078362"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078375"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078384"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078404"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078431"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078444"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078456"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078466"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078481"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078500"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078528"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078550"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078569"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078583"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078620"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078677"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078696"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078712"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078726"
	wait(.02)
	script.Parent.Texture.Texture = "http://www.roblox.com/asset/?id=357078742"
	wait(.02)
end

What should I do to optimize this? I’m thinking that if there’s a way to run the script locally through the client instead of server side, and turn it off on certain devices, that it would reduce lag.

You could perhaps have a water quality setting that determines the delay (you have chosen .02 which is ~60FPS)

if they are needing better performance, maybe .04 or .1

1 Like
local Interval = 0.2
local Enabled = true
local Textures = {
	"http://www.roblox.com/asset/?id=357078195",
	"http://www.roblox.com/asset/?id=357078221",
	"http://www.roblox.com/asset/?id=357078254",
	"http://www.roblox.com/asset/?id=357078304",
	"http://www.roblox.com/asset/?id=357078342",
	"http://www.roblox.com/asset/?id=357078362",
	"http://www.roblox.com/asset/?id=357078375",
	"http://www.roblox.com/asset/?id=357078384",
	"http://www.roblox.com/asset/?id=357078404",
	"http://www.roblox.com/asset/?id=357078431",
	"http://www.roblox.com/asset/?id=357078444",
	"http://www.roblox.com/asset/?id=357078456",
	"http://www.roblox.com/asset/?id=357078466",
	"http://www.roblox.com/asset/?id=357078481",
	"http://www.roblox.com/asset/?id=357078500",
	"http://www.roblox.com/asset/?id=357078528",
	"http://www.roblox.com/asset/?id=357078550",
	"http://www.roblox.com/asset/?id=357078569",
	"http://www.roblox.com/asset/?id=357078583",
	"http://www.roblox.com/asset/?id=357078620",
	"http://www.roblox.com/asset/?id=357078677",
	"http://www.roblox.com/asset/?id=357078696",
	"http://www.roblox.com/asset/?id=357078712",
	"http://www.roblox.com/asset/?id=357078726",
	"http://www.roblox.com/asset/?id=357078742"
}
local Water = {}
for _, _Instance in pairs(workspace:GetDescendants()) do
	if _Instance.Name == "Water" then
		table.insert(Water, _Instance)
	end
end
while true do
	if not Enabled then
		wait(1)
		continue
	end
	for _, texture in pairs(Textures) do
		wait(Interval)
		for _, Water in pairs(Water) do
			Water.Texture.Texture = texture
		end
	end
end

rename your water parts to “Water”, put the localscript in a gui and tie some buttons to the settings at the top

2 Likes

That code is extremely expensive damn. I think the only true way to optimize it is to reduce the lag is to increase the waiting time. Play around with it, and see what is the best cost benefit waiting time(lowest lag possibility, and lowest performance decrease as well).

Interesting concept with the water though with all those textures.

I think I could just have this run in a LocalScript in the PlayerGui, and not put it in a GUI at all, no? I’d make the settings based on device. Is there a way we can tell a player’s frame rate in the game, and base it off of that?

@Pharyx_Styx
What’s the formula for determining the optimal wait time based on expected FPS (.02 for 60, would that mean .04 is for 30, and .1 for 12 FPS?)

1 sec for 60 frames
? sec for 1 frame

60/60 = 1 frame
1/60 = .0166… sec

Unit cancelation
frame / (frame/sec) = sec
→ (frame*sec)/frame = sec

Not sure how to explain this in a chat, but it comes down to
1 divided by your desired fps is the time per frame

The effect and the setting should be local with the setting passed on to any other places if you teleport them. Saving it regardless for later plays.

I feel your approach is wrong. Instead of changing textures you should be changing the part itself. By changing its size and/or cframe you can achieve a similar effect but much less expensive

So using @kylerzong’s script, I could set Interval to 1/Workspace:GetRealPhysicsFPS() in the local script?

And would checking for any changes in the player’s FPS during

for _, texture in pairs(Textures) do
	wait(Interval)
        Interval = 1/Workspace:GetRealPhysicsFPS() ---- constantly check fps
	for _, Water in pairs(Water) do
		Water.Texture.Texture = texture
	end
end

cause any lag, or would I be gtg?

The flowing animation is done on a very large mesh. Also using textures ensures that the various boats players in my game use doesn’t scew up the ocean since there’s no size/cframe editing

well you can make the ocean and the visual representation of the ocean separate perhaps? Have the ocean be 1 part and what the players see another part changing shape size and position

Yeah, that’s what we’re talking about doing via the client, through @kylerzong’s script