Scripting Terrain

Scripting Terrain

10 min


To understand how Terrain works, it is important to know a few of the fundamental concepts behind it. Firstly, Terrain is based on a voxel system. A voxel is basically a point in space, often arranged in a grid. In Roblox, each cell in the voxel grid measures 4x4x4 studs.

To create the terrain effect, points in the voxel grid are assigned a material. This material is then filled in around the voxel to create the terrain. With Roblox’s legacy terrain, the material was shaped into a cube around the voxel (or sometimes a 45 degree slope). With Smooth Terrain however, this is not the case. With Smooth Terrain each voxel now contains an occupancy value along with its material value. This occupancy value defines how full the voxel is with the given material. This value can be anywhere between 0 (almost completely empty) to 1 (very full, sometimes overflowing). When Roblox generates terrain based on these values, the shape of the terrain is organically generated to create smooth curves to accommodate varying occupancy values.


The Terrain/FillBlock function can be used to create terrain from the volume defined by a Part. This can be used to quickly create terrain by simply placing parts where you want the terrain to go. When the terrain is generated the volume will be filled as close as possible by adjusting the occupancy of the voxels the volume overlaps. This is not guaranteed to get a perfect match to the volume but will be the approximate shape. This function takes several parameters:

  • Articles/Understanding CFrame|CFrame: The CFrame of the region you want to fill. As with all CFrames, this can define both a position and an orientation.
  • Vector3 size: The size of the region to be filled. If the CFrame is rotated the size will be rotated accordingly.
  • Enum/Material material: The material to be used when generating the terrain.


Given a Part in the Workspace called Part, the following will generate grass terrain to fill the volume of the part.

game.Workspace.Terrain:FillBlock(game.Workspace.Part.CFrame, game.Workspace.Part.Size, Enum.Material.Grass)



The Terrain/FillBall function creates terrain to fill a spherical volume. This function takes several parameters:

  • Vector3 center: The center of the sphere to be filled.
  • float radius: The radius of the sphere.
  • Enum/Material material: The material to be used when generating the terrain.

This will create a sphere of sand above the center of a place:

game.Workspace.Terrain:FillBall(Vector3.new(0, 100, 0), 50, Enum.Material.Sand)



The Terrain/FillRegion function creates terrain within a defined Region3.

  • Region3 region: The region to be filled.
  • float resolution: The resolution of voxels to fill. Must be set at 4. See .
  • Enum/Material material: The material to be used when generating the terrain.


This will create slate terrain in the region specified. Note that the region is not initially aligned to the voxel grid but the ExpandToGrid function is used to fix that.

local region = Region3.new(Vector3.new(0,0,-3), Vector3.new(4,4,4))
region = region:ExpandToGrid(4)
game.Workspace.Terrain:FillRegion(region, 4, Enum.Material.Slate)


Reading and writing voxels

The functions outlined above do a lot of work to automatically calculate which voxels to fill with terrain and how much occupancy to use. Sometimes you may want to directly read and write to specific voxels to specify the material and occupancy.


Terrain/ReadVoxels takes a Region3 and a resolution and returns the raw voxel data for the region specified. This data is returned as two 3D arrays. The first array contains material values, the second contains occupancy. Both arrays also have a Vector3 property called Size that can be used to determine the size of the arrays in each of their dimensions. As with FillRegion the region supplied must be aligned to the voxel grid. ExpandToGrid can be used to ensure the correct region is used.


Terrain/WriteVoxels allows you to specify specific material and occupancy values for each voxel in a region. Like ReadVoxels and FillRegion the region specified must be aligned to the voxel grid using a method like ExpandToGrid. The material and occupancy arrays must also be the correct size for this function to work properly.



The functions Terrain/FillRegion, Terrain/ReadVoxels, and Terrain/WriteVoxels all require a parameter to define the resolution of the voxels the functions are intended to work with. At the moment this must always be set to 4, as Roblox voxels are currently 4x4x4 studs in size. This setting however is left as a variable as Roblox may implement a smaller voxel resolution at some point. Leaving this as a variable allows code written with the current system to work expecting 4x4x4 voxels to work with any size voxel in the future.


Flood Fill

This LocalScript will flood fill depressions in terrain with water. If the algorithm detects that the fill could potentially go on forever, it will abort the process and not generate any new terrain.

Procedural terrain generation

This example generates terrain as the player walks through the world. This code generates a heightmap using math.noise and fills in the terrain using Terrain/FillBlock.

  • procedural
  • terrain
  • coding