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.