Terrain
Terrain lets you create dynamically morphable environments with little to no lag. It is currently based on a 4×4×4 grid of cells, where each cell has a number between 0 and 1 representing how much the geometry should occupy the cell, and the material of the cell. The occupancy determines how the cell will morph together with surrounding cells, and the result is the illusion of having no grid constraint.
For more information, see Terrain.
Summary
Properties
Enables or disables terrain decoration.
Specifies the length of animated grass.
Returns true if the current game is using the smooth terrain system.
MaterialColors represents the editor for the Material Color feature, and cannot be edited by scripts.
To get the color of a material, use: Terrain:GetMaterialColor() To set the color of a material, use: Terrain:SetMaterialColor()
Displays the boundaries of the largest possible editable region.
The tint of the Terrain water.
Controls how opaque the Terrain's water reflections are.
The transparency of the Terrain water.
Sets the maximum height of the Terrain water waves in studs.
Sets how many times the Terrain water waves will move up and down per minute.
Determines whether a part is immovable by physics.
The angular velocity of the part's assembly.
The center of mass of the part's assembly in world space.
The linear velocity of the part's assembly.
The total mass of the part's assembly.
A reference to the root part of the assembly.
Determines whether the part will physically interact with audio simulation, similar to CastShadow for lighting.
Determines the first parameter for the SurfaceType on the Back face of a part.
Determines the second parameter for the SurfaceType on the Back face of a part.
Determines the type of surface for the back face of a part.
Determines the kind of input for the Back face of a part.
Determines the first parameter for the SurfaceType on the Bottom face of a part.
Determines the second parameter for the SurfaceType on the Bottom face of a part.
Determines the type of surface for the bottom face of a part.
Determines the kind of input for the Bottom face of a part.
Determines the color of a part.
Determines the position and orientation of the BasePart in the world.
Determines whether a part may collide with other parts.
Determines whether the part is considered during spatial query operations.
Determines if Touched and TouchEnded events fire on the part.
Determines whether or not a part casts a shadow.
Describes the world position in which a part's center of mass is located.
Describes the name of a part's collision group.
Describes the automatically set ID number of a part's collision group.
Determines the color of a part.
Indicates the current physical properties of the part.
Determines several physical properties of a part.
Used to control the Elasticity of the part, but it no longer does anything.
Used to enable or disable aerodynamic forces on parts and assemblies.
The actual physical size of the BasePart as regarded by the physics engine.
Used to control the Friction of the part, but now it no longer does anything.
Determines the first parameter for the SurfaceType on the Front face of a part.
Determines the second parameter for the SurfaceType on the Front face of a part.
Determines the type of surface for the front face of a part.
Determines the kind of input for the Front face of a part (-Z direction).
Determines the first parameter for the SurfaceType on the Left face of a part.
Determines the second parameter for the SurfaceType on the Left face of a part.
Determines the type of surface for the left face of a part.
Determines the kind of input for the Left face of a part.
Determines a multiplier for BasePart.Transparency that is only visible to the local client.
Determines whether a part is selectable in Studio.
Describes the mass of the part, the product of its density and volume.
Determines whether the part contributes to the total mass or inertia of its rigid body.
Determines the texture and default physical properties of a part.
The name of MaterialVariant.
Describes the rotation of the part in the world.
Specifies the offset of the part's pivot from its CFrame.
Describes the position of the part in the world.
Time since last recorded physics update.
Determines how much a part reflects the skybox.
Describes the smallest change in size allowable by the Resize() method.
Describes the faces on which a part may be resized.
Determines the first parameter for the SurfaceType on the Right face of a part.
Determines the second parameter for the SurfaceType on the Right face of a part.
Determines the type of surface for the right face of a part.
Determines the kind of input for the Right face of a part (-X direction).
The main rule in determining the root part of an assembly.
Determines a part's change in orientation over time.
The rotation of the part in degrees for the three axes.
Determines the dimensions of a part (length, width, height).
The ratio of the part's density to the density of water determined by the BasePart.Material.
Determines the first parameter for the SurfaceType on the Top face of a part.
Determines the second parameter for the SurfaceType on the Top face of a part.
Determines the type of surface for the top face of a part.
Determines the kind of input for the Top face of a part (+Y direction).
Determines how much a part can be seen through (the inverse of part opacity).
Determines a part's change in position over time.
Methods
(OBSOLETE) No longer does anything.
(OBSOLETE) No longer does anything.
Returns the world position of the center of the terrain cell (x, y, z).
Returns the position of the lower-left-forward corner of the grid cell (x, y, z).
Clears the terrain.
Transforms the legacy terrain engine into the new terrain engine.
Stores a chunk of terrain into a TerrainRegion object so it can be loaded back later. Note: TerrainRegion data does not replicate between server and client.
Returns the number of non-empty cells in the Terrain.
Fills a ball of smooth terrain in a given space.
Fills a block of smooth terrain with a given location, rotation, size, and material.
Fills a cylinder of smooth terrain in a given space.
Fills a Region3 space with smooth terrain.
Fills a wedge-shaped volume of Terrain with the given Enum.Material and the area's CFrame and Size.
Returns the closest CellMaterial from the legacy terrain engine that matches the smooth terrain voxel specified.
Returns current terrain material color for specified terrain material.
Returns if the cell is a water cell.
Applies a chunk of terrain to the Terrain object. Note: TerrainRegion data does not replicate between server and client.
Returns a region of terrain voxel data in table format based on the channel names.
Returns a certain region of smooth terrain in table format.
- ReplaceMaterial(region : Region3,resolution : number,sourceMaterial : Enum.Material,targetMaterial : Enum.Material):()
Replaces the terrain of a material within a region with another material.
- SetCell(x : number,y : number,z : number,material : Enum.CellMaterial,block : Enum.CellBlock,orientation : Enum.CellOrientation):()
Sets the occupancy and material of a specific terrain voxel.
- SetCells(region : Region3int16,material : Enum.CellMaterial,block : Enum.CellBlock,orientation : Enum.CellOrientation):()
Sets the occupancy and material of all terrain voxels in a specific region.
Sets current terrain material color for specified terrain material.
- SetWaterCell(x : number,y : number,z : number,force : Enum.WaterForce,direction : Enum.WaterDirection):()
Sets the specified terrain voxel's material to ''Water'' and sets its occupancy to 1.
Returns the grid cell location that contains the point position.
Returns the grid cell location that contains the point position, preferring empty grid cells when position is on a grid edge.
Returns the grid cell location that contains the point position, preferring non-empty grid cells when position is on a grid edge.
Sets a region of terrain using a dictionary of voxel channel data.
Sets a certain region of smooth terrain using table format.
Apply an angular impulse to the assembly.
Apply an impulse to the assembly at the assembly's center of mass.
Apply an impulse to the assembly at specified position.
Breaks any surface connection with any adjacent part, including Weld and other JointInstance.
Returns whether the parts can collide with each other.
Checks whether you can set a part's network ownership.
Returns a table of parts connected to the object by any kind of rigid joint.
Return all Joints or Constraints that is connected to this Part.
Returns the value of the Mass property.
Returns the current player who is the network owner of this part, or nil in case of the server.
Returns true if the game engine automatically decides the network owner for this part.
OBSOLETE. Returns a CFrame describing where the part is being rendered at.
Returns the base part of an assembly of parts.
Returns a table of all BasePart.CanCollide true parts that intersect with this part.
Returns the linear velocity of the part's assembly at the given position relative to this part.
Returns true if the object is connected to a part that will hold it in place (eg an Anchored part), otherwise returns false.
Creates a joint on any side of the object that has a surface ID that can make a joint.
Changes the size of an object just like using the Studio resize tool.
Sets the given player as network owner for this and all connected parts.
Lets the game engine dynamically decide who will handle the part's physics (one of the clients or the server).
- IntersectAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
Creates a new IntersectOperation from the overlapping geometry of the part and the other parts in the given array.
- SubtractAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
Creates a new UnionOperation from the part, minus the geometry occupied by the parts in the given array.
- UnionAsync(parts : Instances,collisionfidelity : Enum.CollisionFidelity,renderFidelity : Enum.RenderFidelity):Instance
Creates a new UnionOperation from the part, plus the geometry occupied by the parts in the given array.
Gets the pivot of a PVInstance.
Transforms the PVInstance along with all of its descendant PVInstances such that the pivot is now located at the specified CFrame.
Events
Events inherited from BasePartFires when a part stops touching another part as a result of physical movement.
Fires when a part touches another part as a result of physical movement.
Properties
Decoration
Currently enables or disables animated grass on the Grass terrain material, although future modifications of this property may control additional decorative features.
GrassLength
Specifies the length of animated grass on the Grass terrain material, assuming Decoration is enabled. Valid values are between 0.1 and 1.
IsSmooth
Returns true if the current game is using the smooth terrain system. The legacy terrain engine has been removed, so this property will always be true.
MaterialColors
MaterialColors represents the editor for the Material Color feature, and cannot be edited by scripts.
To get the color of a material, use: Terrain:GetMaterialColor()
To set the color of a material, use: Terrain:SetMaterialColor()
WaterWaveSize
Sets the maximum height of the Terrain water waves in studs. This is currently constrained to between 0 and 1.
WaterWaveSpeed
Sets how many times the Terrain water waves will move up and down per minute. This is currently constrained to between 0 and 100.
Methods
AutowedgeCell
(OBSOLETE) No longer does anything.
Parameters
Returns
AutowedgeCells
(OBSOLETE) No longer does anything.
Parameters
Returns
CellCenterToWorld
Returns the world position of the center of the terrain cell (x, y, z).
Parameters
Returns
CellCornerToWorld
Returns the position of the lower-left-forward corner of the grid cell (x, y, z).
Parameters
Returns
Clear
Clears the terrain.
Returns
ConvertToSmooth
Transforms the legacy terrain engine into the new terrain engine.
All places now automatically use the new terrain engine, so this method is obsolete.
Returns
CopyRegion
Stores a chunk of terrain into a TerrainRegion object so it can be loaded back later. Note: TerrainRegion data does not replicate between server and client.
Parameters
Returns
Code Samples
The following code will copy the whole Terrain and clear it. After 5 seconds it will paste the terrain back.
local terrainRegion = workspace.Terrain:CopyRegion(workspace.Terrain.MaxExtents)
workspace.Terrain:Clear()
task.wait(5)
workspace.Terrain:PasteRegion(terrainRegion, workspace.Terrain.MaxExtents.Min, true)
FillBall
Fills a ball of smooth terrain in a given space.
Parameters
The position of the center of the terrain ball.
The radius in studs of the terrain ball.
The Enum.Material of the terrain ball.
Returns
Code Samples
Terrain:FillBall() creates a ball of terrain given a center position, ball radius, and terrain materials.
local Workspace = game:GetService("Workspace")
-- Creates a ball of grass at (0,0,-10) with a radius of 10 studs
Workspace.Terrain:FillBall(Vector3.new(0, 0, -10), 10, Enum.Material.Grass)
FillBlock
Fills a block of smooth terrain with a given location, rotation, size, and material.
Parameters
The position and orientation of the terrain block.
The size in studs of the square block - both the height and width.
The Enum.Material of the terrain block.
Returns
FillCylinder
Fills a cylinder of smooth terrain in a given space. The space is defined using a CFrame, height, and radius.
local Workspace = game:GetService("Workspace")Workspace.Terrain:FillCylinder(CFrame.new(0, 50, 0), 5, 30, Enum.Material.Asphalt)
Parameters
The position and orientation of the terrain cylinder.
The height in studs of the terrain cylinder.
The radius in studs of the terrain cylinder.
The Enum.Material of the terrain cylinder.
Returns
FillRegion
Fills a Region3 space with smooth terrain.
Parameters
Returns
FillWedge
FillWedge() fills a wedge-shaped volume of Terrain with the given Enum.Material and the area's CFrame and size. The orientation of the wedge is the same as an equivalent WedgePart.
Parameters
The position and orientation of the wedge to fill.
The size of the wedge to fill.
The material with which the wedge will be filled.
Returns
GetCell
Returns the closest CellMaterial from the legacy terrain engine that matches the smooth terrain voxel specified. CellBlock will always be ''Solid'' and CellOrientation will always be ''NegZ''.
Parameters
Returns
GetMaterialColor
Returns the current terrain material color for the specified terrain material.
Parameters
Returns
GetWaterCell
Returns if the cell is a water cell. The WaterForce parameter will always be None and the WaterDirection will always be NegX.
Parameters
Returns
PasteRegion
Applies a chunk of terrain to the Terrain object. Note: TerrainRegion data does not replicate between server and client.
Parameters
Returns
Code Samples
Creates some terrain, copies it, then pastes it using the following API:
--[[
Note: The use of int16 variants for these API is the result of legacy code.
The underlying voxel grid system uses Vector3int32 (Vector3).
]]
local Workspace = game:GetService("Workspace")
local Terrain = Workspace.Terrain
-- Create a simple terrain region (a 10x10x10 block of grass)
local initialRegion = Region3.new(Vector3.zero, Vector3.one * 10)
Terrain:FillRegion(initialRegion, 4, Enum.Material.Grass)
-- Copy the region using Terrain:CopyRegion
local copyRegion = Region3int16.new(Vector3int16.new(0, 0, 0), Vector3int16.new(10, 10, 10))
local copiedRegion = Terrain:CopyRegion(copyRegion)
-- Define where to paste the region (in this example, offsetting by 5 studs on the X-axis)
local newRegionCorner = Vector3int16.new(5, 0, 0)
-- Paste the region using Terrain:PasteRegion
Terrain:PasteRegion(copiedRegion, newRegionCorner, true)
ReadVoxelChannels
Returns a region of terrain voxel data in table format based on the channel names.
Parameters
Target region to read from. Must be aligned to the voxel grid. Will throw an error if region is too large; limit is currently 4194304 voxels³.
Voxel resolution. Must be 4.
Array of channel IDs (strings) that need to be accessed from the voxel data. Each channel ID represents a type of data that's stored in voxel. Current supported IDs are {"SolidMaterial", "SolidOccupancy", "LiquidOccupancy"}.
Returns
Returns voxel data as a dictionary based on the channelIds input. Keys represent each channel ID with their respective value as an array of 3D data.
- SolidMaterial — The Enum.Material material of the voxel. Note that Water is not supported anymore; instead, a voxel that contains water will have a value of LiquidOccupancy.
- SolidOccupancy — The occupancy of the voxel's material as specified in the SolidMaterial channel. This is a value between 0 (empty) and 1 (full).
The dictionary also contains a Size key with a value representing the 3D array size of each channel data.
Code Samples
local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local function printRegion(terrain, region)
local channelOutput = terrain:ReadVoxelChannels(region, 4, { "SolidOccupancy", "SolidMaterial", "LiquidOccupancy" })
local size = channelOutput.Size
for x = 1, size.X do
for y = 1, size.Y do
for z = 1, size.Z do
print(
("(%2i, %2i, %2i): %.2f %s %.2f"):format(
x,
y,
z,
channelOutput.SolidOccupancy[x][y][z],
channelOutput.SolidMaterial[x][y][z].Name,
channelOutput.LiquidOccupancy[x][y][z]
)
)
end
end
end
end
local region = Region3.new(REGION_START, REGION_END)
printRegion(workspace.Terrain, region)
ReadVoxels
Returns a certain region of smooth terrain in table format.
Parameters
Target region to read from. Must be aligned to the voxel grid. Will throw an error if region is too large. The limit is currently 4194304 voxels^3.
Voxel resolution. Must be 4.
Returns
Returns raw voxel data as two 3D arrays.
- materials - 3D array of Enum.Material from the target area. Also contains a Size field, equal to the dimensions of the nested arrays.
- occupancies - 3D array of occupancy values from the target area. Also contains a Size field, equal to the dimensions of the nested arrays.
Code Samples
local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local function printRegion(terrain, region)
local materials, occupancies = terrain:ReadVoxels(region, 4)
local size = materials.Size -- Same as occupancies.Size
for x = 1, size.X, 1 do
for y = 1, size.Y, 1 do
for z = 1, size.Z, 1 do
print(("(%2i, %2i, %2i): %.2f %s"):format(x, y, z, occupancies[x][y][z], materials[x][y][z].Name))
end
end
end
end
local region = Region3.new(REGION_START, REGION_END)
printRegion(workspace.Terrain, region)
ReplaceMaterial
ReplaceMaterial replaces terrain of a certain Enum.Material within a Region3 with another material. Essentially, it is a find-and-replace operation on Terrain materials.
Constraints
When calling this method, the resolution parameter must be exactly 4. Additionally, the Region3 must be aligned to the terrain materials grid, i.e. the components of the Region3's minimum and maximum points must be divisible by 4. Use Region3:ExpandToGrid() to make a region compatible with this function.
Parameters
The region in which the replacement operation will occur.
The resolution at which the replacement operation will take place; at the moment this must be exactly 4.
The old material that shall be replaced.
The new material.
Returns
Code Samples
This code sample demonstrates the usage of Terrain:ReplaceMaterial() by replacing grass near the game origin with asphalt. It does this by constructing a Region3 using two Vector3s.
local Workspace = game:GetService("Workspace")
local terrain = Workspace.Terrain
local region = Region3.new(Vector3.new(-20, -20, -20), Vector3.new(20, 20, 20))
local resolution = 4
local materialToReplace = Enum.Material.Grass
local replacementMaterial = Enum.Material.Asphalt
terrain:ReplaceMaterial(region, resolution, materialToReplace, replacementMaterial)
SetCell
Sets the occupancy of the specified terrain voxel to 1, and sets it's material to the closest smooth terrain material that matches the CellMaterial.
CellBlock and CellOrientation have no effect.
Parameters
Returns
SetCells
Sets the occupancy of all terrain voxels in the specified region to 1, and sets their materials to the closest smooth terrain material that matches the CellMaterial.
CellBlock and CellOrientation have no effect.
Parameters
Returns
SetMaterialColor
Sets current terrain material color for specified terrain material. Terrain material will shift its base color toward specified color.
Parameters
Returns
SetWaterCell
Sets the specified terrain voxel's material to ''Water'' and sets its occupancy to 1. WaterDirection and WaterForce no longer have any effect.
Note: This API was intended for Roblox's old terrain system, which has since been removed from the engine.
Parameters
Returns
WorldToCell
Returns the grid cell location that contains the point position.
Parameters
Returns
WorldToCellPreferEmpty
Returns the grid cell location that contains the point position, preferring empty grid cells when position is on a grid edge.
Parameters
Returns
WorldToCellPreferSolid
Returns the grid cell location that contains the point position, preferring non-empty grid cells when position is on a grid edge.
Parameters
Returns
WriteVoxelChannels
Sets a region of terrain using a dictionary of voxel channel data.
Parameters
Target region to write to. Must be aligned to the voxel grid. Will throw an error if region is too large; limit is currently 4194304 voxels³.
Voxel resolution. Must be 4.
Dictionary of voxel data similar to the return value of ReadVoxelChannels(). Keys represent each channel ID with their respective value as an array of 3D data. The dictionary can support single or multiple channel inputs.
- SolidMaterial — The Enum.Material material of the voxel. Note that Water is not supported anymore; instead, a voxel that contains only water should be entered as SolidMaterial = Enum.Material.Air, LiquidOccupancy = x, where x is a number between 0 (exclusive) and 1 (inclusive).
- SolidOccupancy — The occupancy of the voxel's material as specified in the SolidMaterial channel. This should be a value between 0 (empty) and 1 (full).
Returns
Code Samples
local region = Region3.new(Vector3.new(0, 0, 0), Vector3.new(64, 32, 64))
local RESOLUTION = 4
local OCC_EPSILON = 1 / 256
local function generateRandomTerrainInRegion(regionInput)
local region = regionInput:ExpandToGrid(4)
local size = region.Size / 4
local solidMaterials = {}
local solidOccupancies = {}
local waterOcc = {}
for x = 1, size.X do
table.insert(solidMaterials, {})
table.insert(solidOccupancies, {})
table.insert(waterOcc, {})
for y = 1, size.Y do
table.insert(solidMaterials[x], {})
table.insert(solidOccupancies[x], {})
table.insert(waterOcc[x], {})
for z = 1, size.Z do
local mat = if math.random() < 0.5 then Enum.Material.Air else Enum.Material.Sand
local occ = 0
local water = math.random()
if mat == Enum.Material.Sand then
occ = math.random() / 2 + 0.5
if occ > 1 - OCC_EPSILON then
water = 0 -- Solids cannot contain water
end
else
occ = 0
end
table.insert(solidMaterials[x][y], mat)
table.insert(solidOccupancies[x][y], occ)
table.insert(waterOcc[x][y], water)
end
end
end
return { SolidMaterial = solidMaterials, SolidOccupancy = solidOccupancies, LiquidOccupancy = waterOcc }
end
local regionContent = generateRandomTerrainInRegion(region)
workspace.Terrain:WriteVoxelChannels(region, 4, regionContent)
WriteVoxels
Sets a certain region of smooth terrain using table format.
Parameters
Target region to write to. Must be aligned to the voxel grid. Will throw an error if region is too large.
Voxel resolution. Must be 4.
3D array of Enum.Material. Dimensions must exactly match the size of the target region in voxels.
3D array of voxel occupancies (number between 0 and 1). Dimensions must exactly match the size of the target region in voxels.
Returns
Code Samples
Example
local Workspace = game:GetService("Workspace")
local terrain = Workspace.Terrain
local resolution = 4
local region = Region3.new(Vector3.new(0, 0, 0), Vector3.new(16, 28, 20)):ExpandToGrid(resolution)
local materials = {
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.Sand,
Enum.Material.Sand,
Enum.Material.Sand,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Snow, Enum.Material.Air },
},
{
{
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
Enum.Material.CrackedLava,
},
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock, Enum.Material.Rock },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand, Enum.Material.Sand },
{ Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud, Enum.Material.Mud },
{ Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air, Enum.Material.Air },
},
}
local occupancies = {
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 0.5, 0.5, 0.5, 0.5 },
{ 0, 0, 0, 0, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 1, 1, 1, 0.5 },
{ 0, 1, 1, 1, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 1, 1, 1, 0.5 },
{ 0, 1, 1, 1, 0 },
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 0.5, 0.5, 0.5, 0.5, 0.5 },
{ 0, 0, 0, 0, 0 },
},
}
terrain:WriteVoxels(region, resolution, materials, occupancies)
Many terrain methods throw an error if their given region size is too large. The limit is currently 4194304 voxels^3 for ReadVoxels() and WriteVoxels(), and 67108864 voxels^3 for other methods. For methods that take a cframe + size combination (e.g. FillBlock, FillCylinder etc.), then the region volume is calculated from the AABB of the target area.
local REGION_START = Vector3.new(-20, -20, -20)
local REGION_END = Vector3.new(20, 20, 20)
local CFRAME = CFrame.new(0, 20, 0)
local SIZE = 50
local function getRegionVolumeVoxels(region)
local resolution = 4
local size = region.Size
return (size.x / resolution) * (size.y / resolution) * (size.z / resolution)
end
local function isRegionTooLargeForReadWriteVoxels(region)
return getRegionVolumeVoxels(region) > 4194304
end
local function isRegionTooLarge(region)
return getRegionVolumeVoxels(region) > 67108864
end
-- Helper function to get an axis-aligned Region3 from the given cframe and size
local function getAABBRegion(cframe, size)
local inv = cframe:Inverse()
local x = size * inv.RightVector
local y = size * inv.UpVector
local z = size * inv.LookVector
local w = math.abs(x.X) + math.abs(x.Y) + math.abs(x.Z)
local h = math.abs(y.X) + math.abs(y.Y) + math.abs(y.Z)
local d = math.abs(z.X) + math.abs(z.Y) + math.abs(z.Z)
local pos = cframe.Position
local halfSize = Vector3.new(w, h, d) / 2
return Region3.new(pos - halfSize, pos + halfSize):ExpandToGrid(4)
end
-- Specific functions for checking individual methods
local function isRegionTooLargeForFillBall(cframe, radius)
local diameter = radius * 2
return isRegionTooLarge(getAABBRegion(cframe, Vector3.new(diameter, diameter, diameter)))
end
local function isRegionTooLargeForFillBlock(cframe, size)
return isRegionTooLarge(getAABBRegion(cframe, size))
end
local function isRegionTooLargeForFillCylinder(cframe, height, radius)
local diameter = radius * 2
return isRegionTooLarge(getAABBRegion(cframe, Vector3.new(diameter, height, diameter)))
end
local function isRegionTooLargeForFillRegion(region)
return isRegionTooLarge(region)
end
local function isRegionTooLargeForFillWedge(cframe, size)
return isRegionTooLarge(getAABBRegion(cframe, size))
end
local function isRegionTooLargeForReplaceMaterial(region)
return isRegionTooLarge(region)
end
local region = Region3.new(REGION_START, REGION_END)
print(isRegionTooLargeForReadWriteVoxels(region))
print(isRegionTooLargeForFillBall(CFRAME, SIZE))
print(isRegionTooLargeForFillBlock(CFRAME, SIZE))
print(isRegionTooLargeForFillCylinder(CFRAME, SIZE, SIZE))
print(isRegionTooLargeForFillRegion(region))
print(isRegionTooLargeForFillWedge(CFRAME, SIZE))
print(isRegionTooLargeForReplaceMaterial(region))