Minecraft Classic terrain generation in roblox

how are you doing that? because I tried raycasting on every single side on every part on the client and that just causes lag spikes even with just a 6 block Chunk

raycasting? just check if the block is next to an air/transparent block, if any of the faces are exposed then render that block, and keep track of the side that is revealing and put a texture on it.

im using raycasting to check if the blocks surrounding the block is air or a block

I have a big 3d array storing the ID of each block, and another array storing the instances. You can get a block by doing blocks[x][y][z] (although iirc the order is slightly different in my code), so to check if the top face is expose, i check if blocks[x][y + 1][z] has a transparent block.

1 Like

That is unbelievable! I didn’t event think this was even possible on roblox! Awesome job!!!

The added touch that the youtube video demonstrating the Minecraft terrain generate was using bandicam :wink: the good old classic recording software. Perfectly matches with the classic Minecraft vibe too!

hey uhh i am just asking but sorry for replying since the last reply was 53 days ago but
how do i prevent the chunks being small blocks


or is this a test version?

sorry for the late reply (i dont check devforum that often)

you need to add the texture id manually for textures to show up, and the commented out region of the code at the end will generate the whole world instead of one chunk
here are all the textures

founded
thanks
gggggggggggggggggggggggggggggggggggggggggggggggggggggggggg

np, also, i may continue development soon with the introduction of dynamic meshes (should help a ton with the lag)

hey dude sorry again for being such annoying dude again (me)
but anyways can u tell me if the place u sended is the same as the classic place

made by you
is the same file as the file u sended
cuz the file u sended is EXTREMELY laggy
i want the not laggy file by you!!!e21@!e1r12gf,jljll~ç.65çl.ç9çkjç~m;ç.~hçg~çngrt
if you can can u pm me with dat file :sad:

I’ve been working on a similar algorithm. But It’s completely custom and it provides decent results but minecraft algorithm is obviously superior. Would you mind sharing some of your code? Like the generation function that determines the biome noise material and etc?

function generateTerrain(pos2,length,width,island,wall,height,hillweight2,lockedbiome,biomeMaterials)
	-- Loop through the x and y coordinates of the terrain
	-- Non Actor script
	--local result = 
	--runSignal:Fire(pos2,length,width,island,wall,height,hillweight2,lockedbiome,biomeMaterials) -- Fire the event with some argument and get the result
	--print(result) -- Do something with the result
	local lockedbiome=lockedbiome
	local Crystal2=game.ServerStorage.MapObjects.SmallObjects:findFirstChild("Crystal")
	local sizez=(length+1)*20-14
	local size=(width+1)*20-14
	local prevscale=0
	local hilltrigger=false
	local cycle=0
	local prevbn=nil
	local hillroll
	local pos =pos2-Vector3.new(size+4,0,sizez+4)
	--local height=1
	local origheight=height
	local maxheight=20
	local defmat=biomeMaterials[3]
	--	terrain:FillBlock((CFrame.new(pos2)),Vector3.new(size,20,sizez),Enum.Material.Air)
	--spawn(function()	
	--	if mathrandom(1,2)==1 then

	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-5,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.CrackedLava)
	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-6,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.Ground)
	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-7,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.Air)	
	--	else

	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-5,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.Water)
	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-6,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.Ground)
	--	terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-7,sizez/2))),Vector3.new(size,4,sizez),Enum.Material.Air)	
	--		end
	--end)
	-- Define some parameters for the biome selection function
	local biomeScale = mathrandom(5,10) -- The scale of the biome noise
	--end 
	local function selectBiome(n,height)
		local material=defmat -- declare a variable for material
		local color -- declare a variable for color

		-- Loop through the biome thresholds
		for i = 1, #biomeThresholds do
			--	print(n)
			if n <= biomeThresholds[i] then -- if the biome noise value is less than or equal to the threshold
				material = biomeMaterials[i] -- assign the corresponding material from the list
				color = biomeColors[i] -- assign the corresponding color from the list
				break -- exit the loop
			end 		
		end 
		-- If none of the thresholds match, return the default material and color (should not happen)
		return material
	end
	--	pos=pos+Vector3.new(-size/2,0,size/2)
	local	maxheight=maxheight
	for x =pos.x, size - resolution, resolution do
		local hillweight=mathrandom(hillweight2/4,hillweight2) 
		if (Vector3.new(x,0,0)-Vector3.new(pos2.x,0,0)).Magnitude<size then
			--high lower chance
			--local resolution =mathrandom(4,20)	
			for y = pos.z, sizez - resolution, resolution do
				if (Vector3.new(0,0,y)-Vector3.new(0,0,pos2.Z)).Magnitude<sizez then
					-- Calculate the height noise value for this coordinate

					resolution =mathrandom(2,7)*2
					prevscale=biomeScale
					--local biomeScale = mathrandom(8.20)/10

					--	spawn(function()	
					-- The maximum height of the terrain in studs
					biomeScale=math.abs((biomeScale-prevscale)/2+biomeScale)
					local hn = simplexNoise(x, y)
					local scale = biomeScale	
					-- Map the height noise value to a height value
					local h = math.floor(hn * height)
					--SimplexNoise.seedP(101)
					-- Calculate the biome noise value for this coordinate
					local bn =nil 
					--local hn = SimplexNoise.Noise2D(x, y)
					----Noise2D = local function(xin,yin)
					---- Map the height noise value to a height value
					--local h = math.floor(hn * height)
					---- Calculate the biome noise value for this coordinate
					--local bn = SimplexNoise.Noise2D(x * biomeScale + seed * 1000, y * biomeScale + seed * 1000)
					---- Select a material and a color based on the biome noise value
					local chance=mathrandom(1,3)
					--print(chance)
					--if chance==1 then
					bn = perlinNoise(x * biomeScale + seed * mathrandom(500,1000), y * biomeScale + seed * mathrandom(500,1000))
					material = selectBiome(bn) 
					--elseif chance==2 then

					--	material = selectBiome(bn)
					--elseif chance==3 then		
					--	material = selectBiome(hn/1.5)	
					--end
					local subregion1 = Region3.new(
						Vector3.new(x, pos.y-.005, y), -- The minimum point of the subregion
						Vector3.new(x + resolution, pos.y+h, y + resolution) -- The maximum point of the subregion
					)


					if island==2 and material==Enum.Material.Grass then
						material=Enum.Material.Sand
					end	
					--subregion1.Size
					--CFrame.new(subregion1.CFrame)*CFrame.Angles(0, math.rad(mathrandom(-180,180)),0)
					local chance=mathrandom(1,5)
					if 	lockedbiome==nil then
						material=material
					else material=lockedbiome	
					end

					if chance==1 then
						terrain:FillBlock((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)+1), math.rad(mathrandom(-180,180)+1),math.rad(mathrandom(-15,15)+1)),subregion1.Size,material)
						terrain:FillBlock((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)+1), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15)+1)),subregion1.Size,material)
					elseif chance==3 then
						--terrain:FillCylinder()
						terrain:FillCylinder((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size.Y,subregion1.Size.X/2,material)
					elseif chance==4 and material~=Enum.Material.Snow and material~=Enum.Material.Grass and material~=Enum.Material.Sand then
						--terrain:FillCylinder((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size.Y,subregion1.Size.X/2,material)
						terrain:FillBlock((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)
						--terrain:FillWedge((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)
					elseif chance==2 then
						terrain:FillCylinder((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size.Y,subregion1.Size.X/2,material)
						terrain:FillBlock((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)
					elseif chance==5 then
						terrain:FillBall(subregion1.CFrame.Position,subregion1.Size.X/2,Enum.Material.LeafyGrass)
						--
						--terrain:FillCylinder((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size.Y,subregion1.Size.X/2,material)
						--terrain:FillBlock((subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)

					end
					if material==Enum.Material.Ground then
						local chance= mathrandom(1,30)
						if chance==1 then
							local ChestRoll=mathrandom(1,5)
							local Chest=game.ReplicatedStorage.Drops.Chests:FindFirstChild("Chest"..ChestRoll.."")

							local Chest=Chest:Clone()
							Chest:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2+Chest.PrimaryPart.Size.Y/2,0)))
							Chest.Parent=workspace.Trees
						end	
					end

					if material==Enum.Material.Basalt then
						if hilltrigger==false then

							if height> origheight then
								height=height-mathrandom(1,6)/10
								if height<origheight then
									height=origheight
								end
							else
								hillroll=mathrandom(1,hillweight*2)
								if hillroll==1 then
									--biomeScale = mathrandom(1,10)
									hilltrigger=true
								end
								--height = origheight
							end
						elseif height<maxheight then

							height=height+(mathrandom(1,5)/10)
						else
							hilltrigger=false
						end
						if hilltrigger==true then
							hillroll=mathrandom(1,hillweight)
							if hillroll==1 then
								hilltrigger=false
							end
						end 
						--	local Size=Vector3.new(mathrandom(min,max),mathrandom(1,yscale*12),mathrandom(min,max))
						if mathrandom(1,30)==1 then
							local Crystal=Crystal2:Clone()
							RollCrystal(Crystal)
							Crystal:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position-Vector3.new(0,subregion1.Size.Y/2*.8,0)))
							Crystal.Parent=workspace.Trees
						else
							terrain:FillWedge(CFrame.new(mathrandom(-4,4),mathrandom(1,12),mathrandom(-4,4))*(subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)
							terrain:FillBlock(CFrame.new(mathrandom(-4,4),mathrandom(1,8),mathrandom(-4,4))*(subregion1.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size,material)
						end
					end
					--local dif=(subregion2.CFrame.Position-pos)
					--local mod=Vector3.new(dif.X/2,dif.Y,dif.Z/2)
					--local mod2=Vector3.new(dif.X/1.75,dif.Y,dif.Z/1.75)
					--local center=pos+Vector3.new(size/2,-5,size/2)
					if island==true then
						local subregion3 = Region3.new(
							Vector3.new(x, pos.y-(.01+h*1.2), y), -- The minimum point of the subregion
							Vector3.new(x + resolution, pos.y, y + resolution) -- The maximum point of the subregion
						)
						terrain:FillWedge(CFrame.new(subregion3.CFrame.Position-Vector3.new(0,4,0))*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion3.Size,Enum.Material.Rock)

						local subregion3 = Region3.new(
							Vector3.new(x, pos.y-(.01+h*1.2), y), -- The minimum point of the subregion
							Vector3.new(x + resolution, pos.y, y + resolution) -- The maximum point of the subregion
						)
						terrain:FillWedge(CFrame.new(subregion3.CFrame.Position-Vector3.new(0,4,0))*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion3.Size,Enum.Material.Rock)
						--		terrain:FillWedge(CFrame.new(subregion3.CFrame.Position-Vector3.new(0,4,0))*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion3.Size,Enum.Material.Rock)
					end
					if island==1 then
						local subregion3 = Region3.new(
							Vector3.new(x, -16, y), -- The minimum point of the subregion
							Vector3.new(x + resolution, -14, y + resolution) -- The maximum point of the subregion
						)						
						if material~=Enum.Material.Snow and  material~=Enum.Material.Ice then
							terrain:FillCylinder((subregion3.CFrame)*CFrame.Angles(math.rad(mathrandom(-5,5)), math.rad(mathrandom(0,2)),math.rad(mathrandom(-5,5))),1,subregion1.Size.X*4,Enum.Material.Sand)
						else
							terrain:FillCylinder((subregion3.CFrame)*CFrame.Angles(math.rad(mathrandom(-5,5)), math.rad(mathrandom(0,2)),math.rad(mathrandom(-5,5))),1,subregion1.Size.X*4,Enum.Material.Snow)
						end						
						--if mathrandom(1,50)==1 then
						--	local tree=	game.ServerStorage.DungeonGenerator.DesertPlants:FindFirstChild("DesertPlants"..mathrandom(1,#Desertplant)):Clone()
						--	Resize(tree,mathrandom(50,100)/100)
						--task.wait()*-
						--	tree.CFrame=(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion3.Size.Y/2-.1,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
						--end
						--	terrain:FillCylinder((subregion3.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-5,5)),math.rad(mathrandom(-15,15))),1,subregion1.Size.X*5,Enum.Material.Sand)
						local subregion3 = Region3.new(
							Vector3.new(x, pos.y-(.01+h*1.2), y), -- The minimum point of the subregion
							Vector3.new(x + resolution, pos.y, y + resolution) -- The maximum point of the subregion
						)
						terrain:FillWedge(CFrame.new(subregion3.CFrame.Position-Vector3.new(0,4,0))*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion3.Size,Enum.Material.Rock)

						local subregion3 = Region3.new(
							Vector3.new(x, pos.y-(.01+h*1.4), y), -- The minimum point of the subregion
							Vector3.new(x + resolution, pos.y, y + resolution) -- The maximum point of the subregion
						)
						terrain:FillWedge(CFrame.new(subregion3.CFrame.Position-Vector3.new(0,4,0))*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion3.Size,Enum.Material.Rock)


					elseif island==2 then
						--local subregion3 = Region3.new(
						--	Vector3.new(x, -14, y), -- The minimum point of the subregion
						--	Vector3.new(x + resolution, -12, y + resolution) -- The maximum point of the subregion
						--)						
						--terrain:FillCylinder((subregion3.CFrame)*CFrame.Angles(math.rad(mathrandom(-5,5)), math.rad(mathrandom(-5,5)),math.rad(mathrandom(-5,5))),1,subregion1.Size.X*4,Enum.Material.Sand)
						--	terrain:FillCylinder((subregion3.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-5,5)),math.rad(mathrandom(-15,15))),1,subregion1.Size.X*5,Enum.Material.Sand)
						--if mathrandom(1,18)==1 then
						--	placemarineplant(subregion1)
						--end	
					end
					--	terrain:FillWedge((subregion2.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion2.Size,Enum.Material.Rock)
					if material==Enum.Material.Basalt then
						if mathrandom(1,50)==1 then
							local P = math.random(1,22)
							--local TotalTrees = (TotalTrees)+1
							--initialTrees= initialTrees+1
							local Tree = game.ServerStorage.MapObjects.Rubble:FindFirstChild("Rock"..P..""):Clone()
							Tree.Parent = workspace:WaitForChild("Plants")
							--.Alchemy
							Resize(Tree,mathrandom(25,200)/100)
							Tree.Position=subregion1.CFrame.Position+Vector3.new(0,Tree.Size.Y/1.9+subregion1.Size.Y/2,0)
						end						
					end
					if material==Enum.Material.Snow then
						if mathrandom(1,20)==1 then
							local tree=	game.ServerStorage.DungeonGenerator.WinterTree:FindFirstChild("WinterTree"..mathrandom(1,#Winttree)):Clone()
							Resize(tree,mathrandom(50,100)/100)
							--task.wait()
							tree.CFrame=(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1+tree.Size.Y/2,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
							tree.Parent=workspace.Trees	
						end 
					end		

					--terrain:FillCylinder((subregion2.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion2.Size.Y,subregion2.Size.X/2,material)
					--terrain:FillCylinder((subregion2.CFrame)*CFrame.Angles(math.rad(mathrandom(-15,15)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-15,15))),subregion1.Size.Y,subregion1.Size.X/2,material)
					if material==Enum.Material.Sand then
						if mathrandom(1,30)==1 then
							local tree=	game.ServerStorage.DungeonGenerator.DesertPlants:FindFirstChild("DesertPlants"..mathrandom(1,#Desertplant)):Clone()
							Resize(tree,mathrandom(50,100)/100)
							--task.wait()
							tree.CFrame=(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1+tree.Size.Y/2,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
							tree.Parent=workspace.Plants	
						elseif mathrandom(1,10)==2 then

							local tree=	game.ServerStorage.DungeonGenerator.DesertTrees:FindFirstChild("Palmtree"..mathrandom(1,3)):Clone()
							Resize(tree,mathrandom(50,100)/100)
							--task.wait()

							if tree:IsA("Model") then
								if tree.PrimaryPart==nil and tree.Parent~=nil then
									tree.PrimaryPart=tree:FindFirstChildOfClass("BasePart")
								end
								if tree.PrimaryPart~=nil then
									tree:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
								else 
									--	tree:MoveTo
								end	
							else
								tree.CFrame=(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))

							end
							--tree:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-1,0)))

							--task.delay(1,function() tree:MoveTo(tree.PrimaryPart.Position) end)
							tree.Parent=workspace.Trees
						end
					end
					if material==Enum.Material.Grass or  material==Enum.Material.LeafyGrass then
						if mathrandom(1,30)==1 then
							local tree=	game.ServerStorage.MapObjects.Trees:FindFirstChild("Tree"..mathrandom(1,20)):Clone()
							Resize(tree,mathrandom(50,100)/100)
							--task.wait()
							tree:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
							--tree:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-1,0)))

							--task.delay(1,function() tree:MoveTo(tree.PrimaryPart.Position) end)
							tree.Parent=workspace.Trees	
							--	
						elseif mathrandom(1,15)==1 then
							placeplant(subregion1)

						end

					end

					local plantconflict=findNearestplant(subregion1.CFrame.Position,subregion1)			
					local treeconflict=findNearesttree(subregion1.CFrame.Position,subregion1)			
					--if treeconflict~=nil then
					--task.wait()
					--treeconflict:SetPrimaryPartCFrame(CFrame.new(subregion1.CFrame.Position+Vector3.new(0,subregion1.Size.Y/2-.1,0))*CFrame.Angles(math.rad(mathrandom(-10,10)), math.rad(mathrandom(-180,180)),math.rad(mathrandom(-10,10))))
					--end
					--end)
					cycle=cycle+1
					if cycle>=400 then
						cycle=0
						task.wait()
					end
				end
			end	
		end
	end
	--	local maxheight=maxheight/1.2
	spawn(function()	
		local region=	Region3.new(CFrame.new(Vector3.new(pos.x-.005,-.005,pos.z-.005)-Vector3.new(.01+size/2,2,.01+sizez/2)).Position,CFrame.new(Vector3.new(pos.x,2,pos.z)+Vector3.new(.02+size/2,1,.02+sizez/2)).Position)
		--	print(region)
		--wait()
		local poscfram=(CFrame.new(pos+Vector3.new(size/2,1,sizez/2)))
		--terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-4,size/2))),Vector3.new(size+8,8,size+8),Enum.Material.Air)	
		--terrain:FillBlock((CFrame.new(pos+Vector3.new(size/2,-4,size/2))):T,Vector3.new(size+8,8,size+8),Enum.Material.Air)	
		--game.Workspace.Terrain:ReplaceMaterial(region,4,Enum.Material.Ground,Enum.Material.Sand) --task.wait()	
		--game.Workspace.Terrain:ReplaceMaterial(region,4,Enum.Material.Grass,Enum.Material.Sand) --task.wait()	
		--game.Workspace.Terrain:ReplaceMaterial(region,4,Enum.Material.LeafyGrass,Enum.Material.Sand) --task.wait()	
		--terrain:FillCylinder(,Vector3.new(size/2,4,size/2),Enum.Material.Basalt)
		--terrain:FillCylinder((poscfram),4,size/1.9,Enum.Material.Rock)

		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-4,4),-2,mathrandom(-4,4))),4,size/2,Enum.Material.Basalt)
		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-6,6),-4,mathrandom(-6,6))),4,size/2.2,Enum.Material.Asphalt)
		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-8,8),-6,mathrandom(-8,8))),4,size/2.4,Enum.Material.Asphalt)
		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-10,10),-8,mathrandom(-10,10))),4,size/2.8,Enum.Material.Asphalt)
		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-10,10),-10,mathrandom(-10,10))),4,size/3.2,Enum.Material.Asphalt)
		--terrain:FillCylinder((poscfram):ToWorldSpace(CFrame.new(mathrandom(-10,10),-12,mathrandom(-10,10))),4,size/8,Enum.Material.Asphalt)
		local cent =pos2
		if island==true then
			terrain:FillBlock(CFrame.new(pos+Vector3.new(0,0,sizez*2),cent),Vector3.new(size/2,maxheight*1.6+4,sizez/2),Enum.Material.Air)
			terrain:FillBlock(CFrame.new(pos+Vector3.new(size*2+0,0,0),cent),Vector3.new(size/2,maxheight*1.6+4,sizez/2),Enum.Material.Air)
			terrain:FillBlock(CFrame.new(pos+Vector3.new(size*2,0,sizez*2),cent),Vector3.new(size/3,maxheight*1.6+4,sizez/2),Enum.Material.Air)
			terrain:FillBlock(CFrame.new(pos-Vector3.new(.010,0,.010),cent),Vector3.new(size/2,maxheight*1.6+4,sizez/2),Enum.Material.Air)
		end
		--terrain:FillBlock(CFrame.new(pos+Vector3.new(-2,0,sizez/2),cent),Vector3.new(sizez,maxheight*10,10),Enum.Material.Air)
		--terrain:FillBlock(CFrame.new(pos+Vector3.new(size/2,0,-2),cent),Vector3.new(size,maxheight*2+10,10),Enum.Material.Air)
		--terrain:FillBlock(CFrame.new(pos+Vector3.new(size/2,0,sizez+2),cent),Vector3.new(sizez,maxheight*2+10,10),Enum.Material.Air)
		--terrain:FillBlock(CFrame.new(pos+Vector3.new(size+2,0,sizez/2),cent),Vector3.new(size,maxheight*2+10,10),Enum.Material.Air)
		-- define a local function that takes width, length and position as parameters
		--local function createWaterLine(width, length, position)
		-- loop through the x and z coordinates of the water line
		--if typeof(position) == "Vector3" then
		--	-- do something
		--else
		--	print("Waterline Error")
		--	-- handle the error
		--end
		--for x = position.X, position.X + width do
		--	for z = position.Z, position.Z + length do
		--		-- replace the air material with water material at 4 studs height
		--		terrain:ReplaceMaterial(
		--			Region3.new(
		--				Vector3.new(x, position.Y, z),
		--				Vector3.new(x + 1, position.Y + 4, z + 1)
		--			),4,
		--			Enum.Material.Grass,
		--			Enum.Material.Sand
		--		)
		--	end
		--end
		--end

		-- call the local function with some example values
		--createWaterLine(size*2, sizez*2, pos)
		local YPos=cent.Y
		--width=size/20-20/2
		--5+2+1*20=120
		local C=Center:Clone()
		C.Position=pos2
		if wall==true then
			--BuildWall(length,width,YPos,C,true,true)
			--BuildBorder(pos2,YPos,length,width,C,true)
		end	
	end)		
end

This is due to some change roblox made between may 2022 and august 2022, I haven’t made any changes to the place since may 2022 and it wasnt laggy then. However expect to see some updates soon.

1 Like

Also you can make all the surface guis locally rendered to save resources. I have a system procedurally generates the world in chunks as the player explores it. I can provide you a template if you could help me with this.

The algorithm itself is described here. Minecraft Classic map generation algorithm · UnknownShadow200/ClassiCube Wiki · GitHub
If you want to see the code, I provided a place file in a previous comment, the generation code is in workspace.Minecraft.Level

1 Like

That is supremely wonderful! I have been having issue with creating an algorithm such as that. Well anyway thank you for your help. I would implore you to check out this community resource I recently shared. It’s an algorithm that is a chatbot it’s open source and very easy to customize! Artificially Intelligent Chatbot LUAU Algorithm [Open Source] - Resources / Community Resources - Developer Forum | Roblox

I cannot find the file? The classic place you share is not available to be editted in studio. Nevermind I found it :slight_smile:
I’m going to port this algorithm to ROBLOX terrain.
It can be done very simply by identifying the blocks of the specified terrain, filling them with terrain and then destroying the cell.
Or I could go through and replace the function that creates the block with one that creates terrain in that cell. which would be the most efficient method.
Another advantage to using native terrain is that they are highly optimized for rendering.
classic - Roblox

Another way I would improve your algorithm is by potentially utilizing a cache of replicated parts during downtime to prepare for the next generation. It could be as simple as having a cache of already instanced blocks then applying the material and properties to the object. You would have to initialize the cache. This would improve performance and reduce lag spikes. I will apply performance modifications to your code.

Woah, that’s pretty cool! also you’re welcome

Hey guys, if you need a Lua implementation of Java’s random I made one here

This is very good! Nice job on it!