How to check for terrain in an area?

I’m choosing a random position and want to see if I can spawn something there. Of course, if there’s, say, a building, or maybe a mountain there, I don’t want to be able to spawn it.

I’m pretty sure there’s a Method to detect if a part is inside a Vector3, but how would I check for terrain?
My only idea is to just raycast downwards and see if it returns anything, but would that work if the random position is inside the mountain?
Either way, if there’s a better method, let me know, I guess.

Hi, that is the method I would do but I can solve the mountain problem. You could make a table of location ranges.
For example

local badLocations = {
location1Start =,0,0)
Location1End =,16,16)


I don’t know if that code would work because it is late at the time of writing this so just check it. Then you could use a modified version of this code to check

local location = --Location that was chosen in Vector3 format
if(location in badLocations) then
    --Get a new location

Again this won’t work if you just copy and paste this and don’t change it.

Hope this helped!

You can use Terrain:ReadVoxels().

local function isPointInNonEmptyTerrainCell(position: Vector3): boolean
	local regionMinCorner = / 4) * 4, math.floor(position.Y / 4) * 4, math.floor(position.Z / 4) * 4)
	local regionMaxCorner = regionMinCorner +, 4, 4)
	local region =, maxCorner)
	local materials = workspace.Terrain:ReadVoxels(region, 4) -- a 3D array (array of arrays) of occupancies is returned as well but this code doesn't use it so I didn't make a variable for it.
	return materials[1][1][1] ~= Enum.Material.Air

This isn’t perfectly accurate at telling whether a point is inside terrain because the terrain mesh is not necessarily entirely inside the 4x4x4 terrain cells that have an occupancy higher than 0, and it doesn’t necessarily fill a cell entirely unless the occupancy is 1.

What exactly is the point in multiplying all that stuff by 4 and then dividing it by 4?

math.floor(n / 4) * 4 where n is a number gives n rounded down to a number divisible by 4.

In the case of positive n:

  • n / 4 gives how many times 4 fits into n (not cecessarily an integer, for example, two and a half fours fit into ten, so if n == 10, then n / 4 gives 2.5).
  • math.floor(n / 4) rounds this down to an integer (this tells how many whole fours fit into n).
  • math.floor(n / 4) * 4 gives the highest number divisible by four that is less than or equal to n (the next number divisible by four is math.floor(n / 4) * 4 + 4, but it is larger than n).

Well yeah but how is that useful? Like what is that doing in the script what does it accomplish

regionMinCorner is the corner in which all coordinates are less than or equal to the corresponding coordinate in any other corner of the cube-shaped region of the terrain cell in which position is. Position is a world space point that can have any numbers as coordinates.

Terrain cell regions are 4x4x4 cubes, and the origo whose coordinates (0, 0, 0) are divisible by 4 is one cell corner (a corner of the eight cells around origo). Thus, the coordinates of all cell corners are divisible by 4 and any number divisible by 4 is a corner coordinate of some terrain cells.

A point is in a region when it’s in the space between the boundaries of the region. For a given position.X, the cell corner X coordinates (boundary X coordinates of the cell) are math.floor(position.X / 4) * 4 and math.floor(position.X / 4) * 4 + 4. Each of these corner X coordinates is the X coordinate of four corners of the cube-shaped cell region (a cube has 8 corners)). position.X is between these coordinates. When position.X is at the boundary between cells (divisible by four), the code considers it to be in the cell with higher minimum coordinate (in this case position.X and math.floor(position.X / 4) * 4 (which is regionMinCorner.X) are equal).

In short, the code creates a Region3 that contains position and contains exactly one terrain cell. Choosing a higher minimum corner coordinate than what is calculated in the code or a lower maximum corner coordinate would result in the corresponding coordinate of position being outside the region. Choosing a lower minimum corner coordinate or a higher maximum corner coordinate would cause the region to include more than one terrain cell although it would still contain the position coordinate.

Roblox docs should explain everything you need for this:

Maybe these would help you:
1.How can I detect if there is any terrain is in a certain part? - #4 by dthecoolest
2.Check the documentation