Scripting Terrain
Scripting Terrain
Scripting
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.
FillBlock
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.
Example
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)
FillBall
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.
Example:
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)
FillRegion
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.
Example
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.
ReadVoxels
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.
WriteVoxels
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.
Resolution
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.
Examples
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
.