Skip to content

Grid Placement v6.0.2

3D Terrain Painting

Paint, replace, and erase GridMap terrain cells by catalog terrain name.

Status
Current
Version
v6.0.2
Source updated
2026-09-04
Generated on
2026-09-20

Paint, replace, and erase GridMap terrain cells by catalog terrain name: single cells, LINE/RECTANGLE_FILL/RECTANGLE_OUTLINE drags, and erase. Game-authored placement rules evaluate every paint exactly like 2D terrain. FLOOD_FILL has no 3D shape math and fails closed.

The plugin owns no game rules about how terrains behave — ore stays ore because your game says so, not because the plugin knows what ore is. It only consumes your placement rules, validates, and paints into the correct GridMap layers.

Paint one cell

var report:= terrain_service.try_place_terrain_by_name(
	&"grass", cell, grid_map,null, entry, palette)

entry/palette are optional: when omitted, the entry resolves from the service catalog by terrain name. Painting the item a cell already holds fails closed as a no-op, never a success.

Drag shapes

Start a drag, then commit it — the host routes these intents for 3D sessions:

  1. START_TERRAIN_DRAG anchors the drag at the cursor cell.
  2. COMPLETE_TERRAIN_DRAG stamps the shape between anchor and cursor.
  3. COMPLETE_DEMOLISH_DRAG erases the dragged shape instead.

preview_terrain_drag_3d returns the pending shape cells without mutating the world, so hover/drag ghosts read exactly what a commit would stamp.

Author rules for 3D paint

Subclass TilePaintRule and opt in:

func supports_3d_terrain()-> bool:
	return true

func validate_cell(p_context:PlacementValidationContext)-> Array[String]:
	var cell:Vector3i = p_context.cell_3d
	var map:GridMap = p_context.target_map_3d
	# ... your game policy here (tools, ownership, costs) ...
	return []

Rules that do not opt in never run on 3D paints — 2D-authored rules cannot observe 3D coordinates they cannot interpret. Entry/palette rule resolution works the same as 2D (PlacementRuleResolver.resolve_terrain).

Layers and persistence

Paint lands on the explicitly targeted GridMap only — pass it directly or bind it as the session's target_map_3d. Other layers are untouched.

Painted cells persist through the coordinated 3D restore path, which snapshots and restores the full grid (cells, items, orientations). React to edits live through TerrainPlacementService3D.terrain_cell_changed.