How would I reduce lag in random-generated world

Hello! I was wondering how I could reduce the lag in a world where all of the blocks on land are randomly generated. The problem is, there are thousands of parts that cause a ton of lag when the world loads. I have tried using the greedy mesher tutorial, but I don’t understand how I can use it in the game since the greedy mesher tutorial only shows how to do it in a single “type” and it is a little confusing. I was wondering how you could do it with multiple types of blocks (Like grass,dirt,stone) and still be able to destroy and place blocks.

Example of world:
image
Thank you for the support :slight_smile:

2 Likes

You could go for the Minecraft approach, and basically just use chunks for random-generation. This is a little complicated to do but it should do the job nicely.

Basically, in Minecraft, chunks are 16x16 spaces of the world. What you’ll do is basically make it so that every chunk is loaded relative to the distance of the player.

I don’t really want to go too into detail, so here is the official Minecraft wiki page on Chunk loading.

1 Like

I am already trying to go for the minecraft approach, however I do not know how I can reduce the lag.

1 Like

To reduce the lag, what you’ll want to is to create some sort of table that contains all the loaded chunks.

The chunks for all the players are loaded locally to reduce the stress on the server. Whenever a player moves around, it will load chunks for them relative to its position, and will then proceed to unload certain chunks that are too far.

1 Like

But that is not the problem. The problem is that the game lags a ton just for a single chunk to load since it is creating thousands of parts.

1 Like

If you’re gonna go my route you’re gonna have to reduce the chunk rendering to around 2 or maybe even up to 4. Roblox is fairly capable handling massive amounts of parts, however considering how many blocks can be filled within a 16x16x16 space, I think that 4 is the maximum you can go.

1 Like

Yes, however it makes the game almost unplayable for the moments when chunks are loading in because of the amount of parts, this could be made faster with a greedy mesher that converts nearby parts into 1 part which makes it significantly easier to load chunks. The problem is, I do not know how to implement this into my game which has multiple types of blocks.

1 Like

There also was this tutorial on how to script one, but it is not very clear and I do not understand it very well.

1 Like

This may sound stupid, but I guess you can make the Greedy Mesher just check the parts adjacent to it if they’re the same type before merging together. For actual destruction and placing systems, I have no idea how to implement.

1 Like

Oh, well thank you for trying to help.

2 Likes

Woah woah woah you shouldn’t be loading in EVERY single part generated by the algorithm!

Take a tip from Minecraft and only generate what you need visible. Ok well in Minecraft they just merge everything into one mesh, which you could theoretically do with unions but that’s too slow.

You could just generate the visible parts needed by checking if the adjacent blocks to the one you just mined/generated and see if it’s visible. Try taking apart bereza12’s Azure Mines open source kit for something like this. It generates the blocks that are visible, not all of the blocks.

1 Like

Okay! I will try that right now.

1 Like

The way that they use it in the mine is different since the mine is completely flat and all they have to do is when the player mines, just add parts surrounding it. The problem is that it’s hard to tell which parts are visible and which ones are not and there could be holes in the map, so I don’t think this method could work.

1 Like

The only blocks that can be reached/seen are the ones on the very surface of the solid volume. Every block has 6 neighbors. A block on the boundary between air and solid blocks has a combination of neighbors that are air and solid. So adding a check to see if it has both lets us only generate blocks on the boundary.

E.g.

function getCoordinateNeighbors(coordinate)
    local r = {}
    
    for _, nid in pairs(Enum.NormalId:GetEnumItems()) do
        local dir = Vector3.FromNormalId(nid)
        local n = coordinate + dir
        table.insert(r, n)
    end
    
    return r
end

function isSolid(c)
    return getHeightMapValue(c.X, c.Z) >= c.Y
end

function isAir(...)
    return not isSolid(...)
end

function isOnBoundary(c)
    local hasAirN, hasSolidN = false, false
    local isBoundary = false
    
    for _, n in pairs(getCoordinateNeighbors(c)) do
        hasAirN = isAir(n) or hasAirN
        hasSolidN = isSolid(n) or hasSolidN
        if hasAirN and hasSolidN then
            isBoundary = true
            break
        end
    end
end

for x = 1, mapSize do
    for z = 1, mapSize do
        local y = 0
        repeat
            y += 1
            local c = Vector3.new(x, y, z)
            if isOnBoundary(c) then
                --build block
            end
        until isAir(c)
    end
end
1 Like

Greedy meshing isnt an option since we cant modify mesh data in Roblox. But you can combine every row of identical blocks into a single block.

Is this defined somewhere or do I have to create the function?

1 Like

What I did for my game is I made it so the player had like a square grid where it checked if there were voxels there. Or in this case terrain cells. If it did I would ignore it, else I would generate the terrain from the seed. To reduce lag what I did is I made it so that when you are x stuff away it deletes the trees. I noticed that terrain didn’t generate any lag but hey.

1 Like

Yeah, sorry. I also commented on another of OPs posts :sweat_smile: