Optimization for a build

Currently I am attempting to generate a corn maze for a cool horror game concept, and at this time while loading it begins to lag a lot making the game unplayable.

Video:

The mazes corn chunks are put together as unions, and I see a few options here.

I could unload the unions whenever they’re out of view to minimize the amount loaded, but to go about this should I hide them in ServerStorage and then add them back when nearby the player?
Or should I use another way.

The corn itself is supposed to be animated, so I had to make each stalk individual instead of a large group, each stalk is one union and is unloaded and then replaced by an animate-able version, and then once the animation is completed it unloads the animate-able version and reloads the union version.

Even with all of this, it still lags. If there is any way I can fix this, please reply below.

Thank you

Hey, cool idea. This is pretty common in a lot of games with foliage, but a good method would be creating a box part in the size of the chunks and then using that for the server side.

On the client side, clone the corn chunks and position them onto those boxes. This way, you’re rendering less on the server and more on the client, which should render faster if I’m not mistakened, correct me if I’m wrong. This could also make it easier for you to animate the corn. If this doesn’t work for you, you can always try to 3D model the corn to contain less polycount (Perhaps 1k-5k triangles).

1 Like

Oh yeah that reminds me, I do plan to load the maze on the client and have the maze the same for each player, however the monster in this game is invisible and the only way you can tell where it is is by the corn parting. That’s what the animation is for. I planned to load the monster entirely on the client for each player so that each player has its own monster that interacts with the clients environment, so this should work out.

The server never renders anything, only the client does.

This alone wouldnt help performance, although, this method could be used to script a corn render distance on the client, so corn only within x amount of studs is loaded.

Are you referring to FPS performance? In that case, it wouldn’t really improve, no, but I was referring to server memory usage, since that is quite important, especially since he’s cloning visibly dense union operations on the server.

Which is also why I have given a different solution; reducing the polycount by decimating the polygons in a 3D modeling application. Surely that should give some improvements to FPS.

2 Likes

Alright, I have implemented an unloader that utilizes transparency instead of anything else as a placeholder since transparency imitates unloading but doesn’t do anything impactful. Now, how should I unload it? By moving the object to ReplicatedStorage when unloaded, or a different method?

Quick note, I had it load 1370 chunks and the transparency had a small but noticeable impact in lowering FPS, but it was still rendering other properties about the objects in the background so it wasn’t perfect.

Alright! I got it to work.

I’m going to explain how I did this for anyone who comes across this with the same issue.

First, I grabbed the magnitude between the player and the Corn Model’s hitbox which I added in. I then created a variable called “LoadDist” which we will use later as the maximum magnitude number.

I then created an if statement for “hitboxMagnitude < LoadDist”.

After all of that, I added an attribute to each Corn Model to define its parent, and added the index of the parent CornChunk. (Stored in name, I however suggest using an attribute.)

After all of this, when the Model’s magnitude distance from the player (Magnitude below)

(Hitbox.Position-Torso.Position).Magnitude

is LARGER than the maximum distance (LoadDist) it parents the Corn Model to “ReplicatedStorage”.

When the magnitude is SMALLER than the maximum distance it parents the corn model to its respective chunk via the attributes we set earlier.

CornModel.Parent = CornContainer["CornChunk"..tostring(CornModel:GetAttribute("Chunk"))]:WaitForChild("CornStorage")

I made sure to do all of this on the client to help with memory as well.

Thank you to:
@umamidayo
and
@baseparts

for coming up with ideas to help with this.

Oh and I forgot to mention, this can be applied to many things such as chunk loading for voxel sandbox games, and you can load in the chunks like I did via a grid loader.

(Here is what I did)

local gp = workspace.genpart

local gridamount = 150
local unloaddist = 10

for x = 1,gridamount,gp.Size.X do
	for z = 1,gridamount,gp.Size.Z do
		local GridPart = gp:Clone()
		GridPart.Parent = workspace.Container.grid
		GridPart.Anchored = true
		GridPart.CanCollide = false
		GridPart.Position = Vector3.new(x,0,z)
		
		--print("Loaded chunk:",x,0,z)
	end
end

for i,v in pairs(workspace.Container.grid:GetChildren()) do
	local new = rs:WaitForChild("CornChunk"):Clone()
	new.Parent = workspace.Container.corn
	new:PivotTo(v.CFrame)
	new.Name = new.Name..tostring(i)

	v:Destroy()
	
	--print("Loaded cornchunk:",i)

	task.wait() --I suggest making the wait larger if you wish for less lag
end
2 Likes

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