Hi,
I am currently working on a minecraft clone and I wanna know how to make it so water that you can swim in will generate in certain places in the world with the rest of it.
Here are my world generation scripts:
Main Script:
local WorldGenerator = require(script:GetCustomProperty('WorldGenerator'))
_G.Blocks = {}
WorldGenerator.Generate(0,50,0,50)
Block Table Script
local blocks = {}
blocks['Dirt'] = {template = script:GetCustomProperty('Dirt')}
blocks['Grass'] = {template = script:GetCustomProperty('Grass')}
blocks['Stone'] = {template = script:GetCustomProperty('Stone')}
blocks['Air'] = {template = nil}
return blocks
Perlin Noise Script:
perlin = {}
perlin.p = {}
perlin.permutation = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
}
function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end
perlin.permutation = shuffle(perlin.permutation)
perlin.size = 256
perlin.gx = {}
perlin.gy = {}
perlin.randMax = 256
function perlin:load( )
for i=1,self.size do
self.p[i] = self.permutation[i]
self.p[256+i] = self.p[i]
end
end
function perlin:noise( x, y, z, s )
x = (x / (100*s)) + 0.001
y = (y / (100*s)) + 0.001
z = (z / (100*s)) + 0.001
local X = math.floor(x) % 256
local Y = math.floor(y) % 256
local Z = math.floor(z) % 256
x = x - math.floor(x)
y = y - math.floor(y)
z = z - math.floor(z)
local u = fade(x)
local v = fade(y)
local w = fade(z)
local A = self.p[X+1]+Y
local AA = self.p[A+1]+Z
local AB = self.p[A+2]+Z
local B = self.p[X+2]+Y
local BA = self.p[B+1]+Z
local BB = self.p[B+2]+Z
return lerp(w, lerp(v, lerp(u, grad(self.p[AA+1], x , y , z ),
grad(self.p[BA+1], x-1, y , z )),
lerp(u, grad(self.p[AB+1], x , y-1, z ),
grad(self.p[BB+1], x-1, y-1, z ))),
lerp(v, lerp(u, grad(self.p[AB+2], x , y , z-1),
grad(self.p[BA+2], x-1, y , z-1)),
lerp(u, grad(self.p[AB+2], x , y-1, z-1),
grad(self.p[BB+2], x-1, y-1, z-1))))
end
function fade( t )
return t * t * t * (t * (t * 6 - 15) + 10)
end
function lerp( t, a, b )
return a + t * (b - a)
end
function grad( hash, x, y, z )
local h = hash % 16
local u = h < 8 and x or y
local v = h < 4 and y or ((h == 12 or h == 14) and x or z)
return ((h % 2) == 0 and u or -u) + ((h % 3) == 0 and v or -v)
end
perlin:load()
return perlin
World Generator Script:
local perlinNoise = require(script:GetCustomProperty('PerlinLIB'))
local blockTable = require(script:GetCustomProperty('BlockTable'))
local WorldGenerator = {}
local xStart = 0
local xEnd = 0
local yStart = 0
local yEnd = 0
local maxHeight = 32
local maxDown = -16
local caveScale = 0.08
local caveSpawnRate = -0.3
local entranceSpawnRate = -0.7
function WorldGenerator.Generate(xStartP, xEndP, yStartP, yEndP)
xStart = xStartP
xEnd = xEndP
yStart = yStartP
yEnd = yEndP
for x = xStart - 1, xEnd + 1 do
_G.Blocks[x] = {}
for y = yStart - 1, yEnd + 1 do
_G.Blocks[x][y] = {}
if x < xStart or x > xEnd or y < yStart or y > yEnd then
for z = maxDown - 1, maxHeight + 1 do
if not _G.Blocks[x][y][z] then
_G.Blocks[x][y][z] = {blockInfo = blockTable['Air'], isSpawned = true}
end
end
else
local height = math.floor(perlinNoise:noise(x,y,0,0.1) * 10)
for z = maxDown, height do
local shouldSpawn = (perlinNoise:noise((x + 999) / 2, (y + 999) / 4, z, caveScale) > caveSpawnRate) and (perlinNoise:noise((x + 999) / 4, (y + 999) / 2, z, caveScale) > caveSpawnRate) and (perlinNoise:noise((x + 999) / 2, (y + 999) / 2, z / 4, caveScale) > caveSpawnRate)
local shouldSpawnEntrance = (perlinNoise:noise((x + 999) / 2, (y + 999) / 4, z, caveScale) > entranceSpawnRate) and (perlinNoise:noise((x + 999) / 4, (y + 999) / 2, z, caveScale) > entranceSpawnRate) and (perlinNoise:noise((x + 999) / 2, (y + 999) / 2, z / 4, caveScale) > entranceSpawnRate)
if z == height - 1 then
if shouldSpawnEntrance then
_G.Blocks[x][y][z] = {blockInfo = blockTable['Grass'], isSpawned = false}
else
_G.Blocks[x][y][z] = {blockInfo = blockTable['Air'], isSpawned = true}
end
elseif z >= height - 3 then
if shouldSpawnEntrance then
_G.Blocks[x][y][z] = {blockInfo = blockTable['Dirt'], isSpawned = false}
else
_G.Blocks[x][y][z] = {blockInfo = blockTable['Air'], isSpawned = true}
end
elseif z == maxDown then
_G.Blocks[x][y][z] = {blockInfo = blockTable['Stone'], isSpawned = false}
else
if shouldSpawn then
_G.Blocks[x][y][z] = {blockInfo = blockTable['Stone'], isSpawned = false}
else
_G.Blocks[x][y][z] = {blockInfo = blockTable['Air'], isSpawned = true}
end
end
end
for z = height, maxHeight do
_G.Blocks[x][y][z] = {blockInfo = blockTable['Air'], isSpawned = true}
end
end
if math.random(1,3) == 1 then
Task.Wait()
end
end
Task.Wait()
end
WorldGenerator.SpawnBlocks()
end
function WorldGenerator.isBlockSurrounded(x,y,z)
if x == xStart or y == yStart or x == xEnd or y == yEnd or z == maxHeight or z == maxDown then
return false
end
if _G.Blocks[x+1][y][z].blockInfo.template == nil then
return false
elseif _G.Blocks[x-1][y][z].blockInfo.template == nil then
return false
elseif _G.Blocks[x][y+1][z].blockInfo.template == nil then
return false
elseif _G.Blocks[x][y-1][z].blockInfo.template == nil then
return false
elseif _G.Blocks[x][y][z+1].blockInfo.template == nil then
return false
elseif _G.Blocks[x][y][z-1].blockInfo.template == nil then
return false
end
return true
end
function WorldGenerator.SpawnSurroundingBlocks(x,y,z)
if _G.Blocks[x+1][y][z].blockInfo.template ~= nil and not _G.Blocks[x+1][y][z].isSpawned then
WorldGenerator.SpawnBlock(x+1,y,z,_G.Blocks[x+1][y][z].blockInfo.template)
end
if _G.Blocks[x-1][y][z].blockInfo.template ~= nil and not _G.Blocks[x-1][y][z].isSpawned then
WorldGenerator.SpawnBlock(x-1,y,z,_G.Blocks[x-1][y][z].blockInfo.template)
end
if _G.Blocks[x][y+1][z].blockInfo.template ~= nil and not _G.Blocks[x][y+1][z].isSpawned then
WorldGenerator.SpawnBlock(x,y+1,z,_G.Blocks[x][y+1][z].blockInfo.template)
end
if _G.Blocks[x][y-1][z].blockInfo.template ~= nil and not _G.Blocks[x][y-1][z].isSpawned then
WorldGenerator.SpawnBlock(x,y-1,z,_G.Blocks[x][y-1][z].blockInfo.template)
end
if _G.Blocks[x][y][z+1].blockInfo.template ~= nil and not _G.Blocks[x][y][z+1].isSpawned then
WorldGenerator.SpawnBlock(x,y,z+1,_G.Blocks[x][y][z+1].blockInfo.template)
end
if _G.Blocks[x][y][z-1].blockInfo.template ~= nil and not _G.Blocks[x][y][z-1].isSpawned then
WorldGenerator.SpawnBlock(x,y,z-1,_G.Blocks[x][y][z-1].blockInfo.template)
end
end
function WorldGenerator.SpawnBlocks()
for x = xStart, xEnd do
for y = yStart, yEnd do
for z = maxDown, maxHeight do
if not WorldGenerator.isBlockSurrounded(x,y,z) then
if _G.Blocks[x][y][z].blockInfo.template ~= nil then
WorldGenerator.SpawnBlock(x,y,z,_G.Blocks[x][y][z].blockInfo.template)
end
end
end
end
Task.Wait()
end
end
function WorldGenerator.SpawnBlock(x,y,z,block)
local block = World.SpawnAsset(block, {position = Vector3.New(x,y,z) * 100})
_G.Blocks[x][y][z].isSpawned = true
end
return WorldGenerator