Skip to content

Terrain

Rolling ground made from a height map: hills, valleys and ramps that you sculpt in Rally Studio or from scripts.

  • Inherits: Instance
  • Creatable: Yes: new Terrain(), or Instance.new('Terrain', parent).
  • Replication: Replicated: clients get a copy, and changes the server makes reach them.

A Terrain covers size.x × size.z studs centered on position. Its ground is a grid of resolution × resolution height samples, each between 0 and size.y studs above position.y. The grid is stored row by row in heights: rows run along z, and each row runs along x. Empty heights is flat ground at position.y.

Characters walk on terrain, parts land on it, raycasts hit it and parts touching it fire touched with the Terrain as the argument. Edit it with sculpt, paint and generate, or assign heights and materials yourself. Each edit on the server sends the whole height map to every player, so edit occasionally rather than every frame.

In a 2D game the ground line is the terrain’s slice at position.z (its middle row of samples), drawn filled down below the terrain’s base.

Type: Vector3 · Default: new Vector3(0, 0, 0) · Access: read/write · Replicates: yes

Center of the terrain at height 0 (its lowest possible point).

Type: Vector3 · Default: new Vector3(256, 64, 256) · Access: read/write · Replicates: yes

Width (x), tallest height (y) and depth (z) in studs.

Type: number · Default: 64 · Range: 2 to 256 (clamped) · Access: read/write · Replicates: yes

Height samples along each side (more = finer detail).

Rounded to a whole number.

Type: number[] · Default: [] · Access: read/write · Replicates: yes

resolution × resolution heights in studs, rows along z, each row along x. Empty is flat.

Assign a new array to change it: changing the array in place isn’t noticed. Heights are rounded to 0.01 studs, and data saved at another resolution is resampled. More than 65,536 samples (256 × 256) throws a TypeError.

Type: TerrainMaterial · Default: 'grass' · Access: read/write · Replicates: yes

Material where none is painted.

Type: number[] · Default: [] · Access: read/write · Replicates: yes

Painted material per sample (indexes into grass, sand, rock, snow, mud, ice). Empty uses material.

Indexes are 0 grass, 1 sand, 2 rock, 3 snow, 4 mud and 5 ice; anything else reads as 0. Like heights, assign a new array to change it.

Inherited from Instance: name, archivable, id, className, parent, destroyed

getHeight(x: number, z: number): number | null

World height of the ground at (x, z), or null outside the terrain.

sculpt(stroke: TerrainStroke): void

Raises, lowers, smooths or flattens a circle of ground (see TerrainStroke).

Heights stay between 0 and size.y. See TerrainStroke.

paint(stroke: TerrainPaintStroke): void

Paints a material onto a circle of ground.

See TerrainPaintStroke.

generate(options: Partial<Omit<TerrainGenerateOptions, 'size' | 'resolution'>> = {}): void

Replaces the ground with random hills (the same seed gives the same hills).

options takes seed (a number or a string; the default is 1), hilliness (0 is nearly flat, 1 is mountains; the default is 0.5) and autoPaint (default true: sand low down, rock on steep slopes, snow on peaks). It uses the terrain’s own size and resolution.

Inherited from Instance: getPropertyChangedSignal, setAttribute, getAttribute, getAttributes, getAttributeChangedSignal, getChildren, getDescendants, findFirstChild, findFirstChildOfClass, findFirstChildWhichIsA, findFirstAncestor, findFirstAncestorWhichIsA, waitForChild, isA, isDescendantOf, isAncestorOf, getFullName, clearAllChildren, destroy, clone, toString

Inherited from Instance: changed, childAdded, childRemoved, descendantAdded, descendantRemoving, ancestryChanged, destroying, attributeChanged

import { Part, Terrain, Vector3, workspace } from '@rally/sdk';
const ground = new Terrain();
ground.size = new Vector3(512, 80, 512);
ground.resolution = 128;
ground.generate({ seed: 42, hilliness: 0.6 });
ground.parent = workspace;
// Put a crate on the ground.
const y = ground.getHeight(10, -20); // null outside the terrain
if (y !== null) {
const crate = new Part();
crate.size = new Vector3(4, 4, 4);
crate.position = new Vector3(10, y + 2, -20);
crate.parent = workspace;
}
// Dig a crater, then level a spot to build on and pave it with rock.
ground.sculpt({ x: 0, z: 0, radius: 12, strength: 6, mode: 'lower' });
ground.sculpt({ x: 60, z: 60, radius: 20, strength: 1, mode: 'flatten' });
ground.paint({ x: 60, z: 60, radius: 20, material: 'rock' });