local Terrain = game.Workspace.Terrain
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- Configuration
local CHUNK_SIZE = 32
local RENDER_DISTANCE = 5
local NOISE_SCALE = 0.005
local TERRAIN_SCALE = 40
local WATER_LEVEL = 1
local SEED = math.random(1, 1000000)
local HOUSE_CHANCE = 0.01 -- 1% chance for a house to spawn in each chunk
-- Biome Configuration
local BIOMES = {
{name = "Plains", threshold = 0.3, material = Enum.Material.Grass},
{name = "Forest", threshold = 0.6, material = Enum.Material.LeafyGrass},
{name = "Desert", threshold = 0.8, material = Enum.Material.Sand},
{name = "Snow", threshold = 1, material = Enum.Material.Snow}
}
-- Store generated chunks
local generatedChunks = {}
-- Get the House model
local houseModel = game.Workspace:FindFirstChild("House")
if not houseModel then
error("House model not found in Workspace")
end
-- Improved noise function with seed and octaves
local function improvedNoise(x, z, octaves)
local total = 0
local frequency = 1
local amplitude = 1
local maxValue = 0
for i = 1, octaves do
total = total + math.noise(x * NOISE_SCALE * frequency + SEED, z * NOISE_SCALE * frequency - SEED) * amplitude
maxValue = maxValue + amplitude
amplitude = amplitude * 0.5
frequency = frequency * 2
end
return total / maxValue
end
-- Function to determine biome
local function getBiome(noise)
for _, biome in ipairs(BIOMES) do
if noise <= biome.threshold then
return biome
end
end
return BIOMES[#BIOMES]
end
-- Function to generate terrain for a single chunk
local function generateChunk(chunkX, chunkZ)
local chunkKey = chunkX .. "," .. chunkZ
if generatedChunks[chunkKey] then return end
local heightMap = {}
for x = 0, CHUNK_SIZE - 1 do
heightMap[x] = {}
for z = 0, CHUNK_SIZE - 1 do
local worldX = chunkX * CHUNK_SIZE + x
local worldZ = chunkZ * CHUNK_SIZE + z
local noise = improvedNoise(worldX, worldZ, 4)
local biomeNoise = improvedNoise(worldX * 0.25, worldZ * 0.25, 2)
local biome = getBiome(biomeNoise)
local height = math.floor(noise * TERRAIN_SCALE + 10)
heightMap[x][z] = height
if height > WATER_LEVEL then
Terrain:FillBlock(CFrame.new(worldX, height / 2, worldZ), Vector3.new(1, height, 1), biome.material)
else
Terrain:FillBlock(CFrame.new(worldX, WATER_LEVEL / 2, worldZ), Vector3.new(1, WATER_LEVEL, 1), Enum.Material.Water)
end
end
end
-- Randomly place a house in the chunk
if math.random() < HOUSE_CHANCE then
local x = math.random(0, CHUNK_SIZE - 1)
local z = math.random(0, CHUNK_SIZE - 1)
local worldX = chunkX * CHUNK_SIZE + x
local worldZ = chunkZ * CHUNK_SIZE + z
local height = heightMap[x][z]
if height > WATER_LEVEL then
local newHouse = houseModel:Clone()
newHouse.Parent = game.Workspace
-- Find a suitable part to use as the PrimaryPart
local primaryPart = newHouse:FindFirstChildWhichIsA("BasePart")
if primaryPart then
newHouse.PrimaryPart = primaryPart
newHouse:SetPrimaryPartCFrame(CFrame.new(worldX, height + 1, worldZ))
else
warn("House model does not have a suitable part to use as PrimaryPart")
newHouse:Destroy()
end
end
end
generatedChunks[chunkKey] = true
end
-- Function to update terrain around the player
local function updateTerrain(player)
local character = player.Character
if not character then return end
local position = character.PrimaryPart.Position
local chunkX = math.floor(position.X / CHUNK_SIZE)
local chunkZ = math.floor(position.Z / CHUNK_SIZE)
for x = -RENDER_DISTANCE, RENDER_DISTANCE do
for z = -RENDER_DISTANCE, RENDER_DISTANCE do
generateChunk(chunkX + x, chunkZ + z)
end
end
end
-- Clear existing terrain
Terrain:Clear()
-- Update terrain when a player's character spawns
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
wait(1)
updateTerrain(player)
end)
end)
-- Continuously update terrain as players move
local lastUpdate = 0
local UPDATE_INTERVAL = 0.5
RunService.Heartbeat:Connect(function(deltaTime)
lastUpdate = lastUpdate + deltaTime
if lastUpdate >= UPDATE_INTERVAL then
for _, player in ipairs(Players:GetPlayers()) do
updateTerrain(player)
end
lastUpdate = 0
end
end)
Changelog: Fixed the issue with setting the PrimaryPart of the house model. Now it searches for a suitable BasePart to use as the PrimaryPart before setting the CFrame.