Blitz3D+ Command Reference

ModifyTerrain terrain,terrain_x,terrain_z,height#[,realtime]

Parameters

terrain - terrain handle

terrain_x - grid x coordinate on the terrain

terrain_z - grid z coordinate on the terrain

height# - new height for that grid point, in the range 0 to 1

realtime (optional) - legacy flag, kept for source compatibility; False (default)

Description

Sets the height of a single point on a terrain's grid.

This is how you sculpt a landscape in code rather than painting it into a height map. Loop over the grid writing heights from a Sin/Cos pattern or from your own noise function to build a world at startup, or call it a few points at a time while the game runs to blow a crater in the ground, raise a bridge, or let the player dig.

Heights are always in the range 0 to 1, whatever size the terrain is in the world - 0 is the terrain's base and 1 is its ceiling. Anything you pass outside that range is clamped rather than rejected, so height 2.0 stores as 1.0. The value is kept as a 16-bit number, so reading it back with TerrainHeight can return something a hair off what you wrote (0.5 comes back as 0.500008). The world height that comes out depends on the terrain's y scale: with ScaleEntity terrain,10,50,10, a stored height of 0.5 is 25 world units above the terrain's origin.

Grid coordinates run from 0 to the value TerrainSize returns. Watch out for the wrap: index grid_size shares its storage with index 0, so a sculpting loop written For x=0 To grid_size overwrites its own first column with its last one. Loop to grid_size-1. Coordinates outside that range are silently ignored - no error, no effect - which makes a mistyped loop bound quietly do nothing rather than crash.

The realtime parameter is a leftover from the original engine, where True forced an immediate rebuild of the terrain's internal detail data and False let it wait for the next RenderWorld. The modern renderer ignores it: the height itself changes straight away, affected bounds metadata is invalidated, and the adaptive error tree and visible mesh are regenerated lazily before they are next needed. Passing True or False makes no difference to what you see, and it is no longer a performance decision.

There is no cost worth worrying about in a handful of calls per frame, but a full re-sculpt of a 512 terrain is a quarter of a million calls, so do that at load time rather than in your main loop. In Extended mode you can wrap a burst of edits in BeginTerrainUpdate and EndTerrainUpdate so the rebuild happens once for the whole batch.

See also: TerrainHeight, CreateTerrain, TerrainSize, TerrainY, BeginTerrainUpdate, ModifyTerrainHole.

Example

; ModifyTerrain Example
; ---------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

; Terrain layout: 32 grid squares, scaled to 10 units per square
terra_size=32
x_scale=10
y_scale=50
z_scale=10

; Overlook the terrain from a fixed camera
camera=CreateCamera()
PositionEntity camera,(terra_size*x_scale)/2,120,-60
RotateEntity camera,35,0,0

light=CreateLight()
RotateEntity light,45,45,0

; Create a flat terrain to sculpt
terrain=CreateTerrain(terra_size)
ScaleEntity terrain,x_scale,y_scale,z_scale

; Texture the terrain
grass_tex=LoadTexture("media/MossyGround.BMP")
EntityTexture terrain,grass_tex

; A red marker showing which grid point we will sculpt
marker=CreateSphere(8)
EntityColor marker,255,60,60
EntityFX marker,1

marker_x=terra_size/2
marker_z=terra_size/2

While Not KeyDown(1)

    ; Cursor keys step the marker across the terrain grid
    If KeyHit(205) And marker_x<terra_size Then marker_x=marker_x+1
    If KeyHit(203) And marker_x>0 Then marker_x=marker_x-1
    If KeyHit(200) And marker_z<terra_size Then marker_z=marker_z+1
    If KeyHit(208) And marker_z>0 Then marker_z=marker_z-1

    ; Read the current height (0 to 1) at the marker's grid point
    height#=TerrainHeight(terrain,marker_x,marker_z)

    ; Hold Space to raise the ground, Z to lower it.
    ; ModifyTerrain sets the height of one grid point.
    If KeyDown(57) And height<1
        height=height+0.005
        ModifyTerrain terrain,marker_x,marker_z,height
    EndIf
    If KeyDown(44) And height>0
        height=height-0.005
        ModifyTerrain terrain,marker_x,marker_z,height
    EndIf

    ; Sit the marker on the sculpted ground
    PositionEntity marker,marker_x*x_scale,height*y_scale+2,marker_z*z_scale

    RenderWorld

    Text 0,0,"Cursor keys: move marker   Hold Space: raise   Hold Z: lower   Esc: exit"
    Text 0,20,"ModifyTerrain terrain,"+marker_x+","+marker_z+","+height

    Flip

Wend

End

Index