Skip to content

Discrete Tile Terrain MCP ​

Use this Skill when an AI agent must edit a terrain scene through the full SCE Editor MCP. It covers the discrete tile terrain workflow. It does not replace the separate Landscape continuous-heightfield workflow or Runtime MCP inspection.

Product boundary ​

  • Discrete tile terrain uses layer-based heights. height=1 means one discrete layer.
  • Landscape is a separate continuous heightfield backend; inspect capability before choosing tools.
  • Users choose semantic surface styles and TileSets. They do not choose internal cliff prefab paths.
  • Different TileSets may coexist and use their own matching cliff proxies.
  • A non-zero height edit that crosses TileSets with different TileThickness is rejected with terrain_height_tile_thickness_inconsistent; split the edit by compatible thickness.
  • Core authoring is Preview/Early Access ready. Runtime terrain.snapshot exposes an explicit partial-observation contract: inspect observation.unsupported_fields, observation.incomplete_fields, sampling, tile_sets, water, and roads before interpreting empty values. tile_sets.status=catalog_available exposes the loaded TileSet/style catalog. When tile_sets.distribution_status=available, tile_sets.distribution reports runtime tile-style counts, TileSet mapping, and map_size_tiles; an empty or unreadable runtime map is reported as no_data. Detailed water/road topology remains unsupported at runtime; water presence is only a texture-label inference when available.

Preconditions ​

  1. Connect to the full Editor MCP, not standalone TriggerMcpHost.
  2. Call editor_get_context.
  3. If needed, use editor_open_project or editor_open_scene, then editor_lifecycle_wait.
  4. Confirm editor_get_context.ready_state == "scene_ready".
  5. Call terrain_get_scene_summary, terrain_get_state, and usually terrain_list_tile_sets.

Reuse the same Editor process. Serialize lifecycle and Terrain writes; if the editor is busy, wait for the reported operation.

Mutation protocol ​

For every mutation:

text
list/query options -> terrain_preview_* -> inspect plan and diagnostics
-> terrain_apply_* -> terrain_get_state / terrain_list_history
-> optional terrain_undo or terrain_redo -> explicit save -> validate/reload

Carry the latest preview token/hash into Apply. Do not blindly retry an expired preview or a stale history state. A successful Apply changes memory and history; it does not generally save the map automatically.

Tool selection ​

Scene and state ​

  • terrain_get_scene_summary: backend, dimensions, dirty state, projection summary.
  • terrain_get_state: history state, save checkpoint, bake flags, selection.
  • terrain_list_history: stable transaction types and affected objects/fields.
  • terrain_validate_scene: projection, manifest, PNG/JSON and source hash validation.

Surfaces and TileSets ​

text
terrain_list_surface_styles
-> terrain_list_surface_textures(style_id)
-> terrain_preview_surface_paint
-> terrain_apply_surface_paint

Use terrain_list_tile_sets before TileSet changes. For a whole-tile switch:

text
terrain_preview_tile_set_paint -> terrain_apply_tile_set_paint

Do not expose or invent prefab paths. Surface style is the user-facing semantic choice; automatic cliff matching remains the default.

Project-owned surface asset import is a separate Preview/Apply workflow. Read terrain-custom-textures, then use terrain_preview_project_surface_import / terrain_apply_project_surface_import and wait for the asynchronous operation. Rebuilding an existing complete catalog uses terrain_preview_project_surface_generate / terrain_apply_project_surface_generate. These tools write project resources; they do not paint the scene, create an Undo transaction, or save the current scene.

Height ​

text
terrain_preview_height_edit -> terrain_apply_height_edit

For discrete tile terrain, send discrete layer values, not world Z values. Inspect tile_set_diagnostics, tile_set_thickness_mixed, topology validation, and affected counts. If the result reports terrain_height_tile_thickness_inconsistent or terrain_height_topology_unsupported, assume no mutation occurred and do not retry unchanged.

Water, ramps and roads ​

text
terrain_preview_water_edit -> terrain_apply_water_edit
terrain_list_ramp_styles(tile_set_id?)
-> terrain_preview_ramp_edit -> terrain_apply_ramp_edit
terrain_list_road_styles
-> terrain_preview_road_edit -> terrain_apply_road_edit

Water planning includes shoreline topology. Ramp styles belong to a TileSet; split polylines by TileSet when needed. Legacy path tools also edit ramp topology. Roads use region, operation=paint/erase, style_id from terrain_list_road_styles and optional density=0..100. Road Apply paints road IDs, texture and boundary decorations; erase preserves painted surface texture.

Cracks, painted collision and sight blocking ​

Use terrain_preview_crack_edit / terrain_apply_crack_edit for region-based terrain-edge cracks. Crack topology and connected-water conversion may affect terrain outside the selected region.

Use terrain_preview_collision_edit / terrain_apply_collision_edit for manual collision cells. Paint adds native collision_flags bits, default4094; erase uses the interactive brush semantics for all collision types. Native Unwalkable=2, Unflyable=4, Unbuildable=8, Unfloatable=64, Unamphibious=128, UnItemplacable=256, Cliff=512, Higher=1024, Lower=2048. These are scene-authoring bit values.

Use terrain_preview_sight_edit / terrain_apply_sight_edit for sight cells. Paint fills unblocked cells; erase reduces one layer. Both grid tools select cell centers within region. Query with terrain_query_collision / terrain_query_sight; split queries when cells_truncated is true (256 returned cells maximum).

Surface2D static collision includes baked terrain/decorations and manual collision cells. Manual collision queries/erase affect only the manual layer. A visible StaticMesh alone does not establish Surface2D blocking. Save and reload before claiming the baked runtime result is verified. Reuse one editor process to avoid competing saves. For a Unit dash stopped by these obstacles, read dash-static-collision.

Example: paint a 128-by-128 manual collision region (native Unwalkable bit), then query the same region. Pass the Preview token/hash into Apply without changing the other arguments:

json
{
  "operation": "paint",
  "region": {"shape": "rectangle", "min": {"x": 320, "y": 320}, "max": {"x": 448, "y": 448}},
  "collision_flags": 2
}

Do not reuse native numeric collision_flags as runtime StaticCollisionMask values; use the runtime enum names. Empty crack erasure is a successful no-op. Validate erase by querying grid values or previewing erasure again, then Undo and verify the original data returns. Checking only the history cursor does not prove data restoration.

Decorations ​

  • Query resources with terrain_list_decoration_resources.
  • Query explicit placed instances with terrain_query_decorations.
  • Do not treat automatic cliff/tile proxy decorations as editable instances.
  • Use terrain_preview_decoration_edit / terrain_apply_decoration_edit for place, move, remove, rename.
  • One instance may combine one move and one rename in one command; remove must remain separate.
  • Use terrain_preview_decoration_scatter / terrain_apply_decoration_scatter with a stable seed for reproducibility.

Scene atmosphere ​

For .lightgroup ambient light, fog, sun direction, environment textures, reflection and post-processing, use terrain_get_atmosphere -> terrain_preview_atmosphere_edit -> terrain_apply_atmosphere_edit. Read atmosphere-mcp for typed partial patches, shared asset handling, explicit save and readback. Point/spot lights use terrain_query_lights -> terrain_preview_light_edit -> terrain_apply_light_edit.

Save and reload ​

For Terrain edits:

text
terrain_save_scene -> terrain_validate_scene
-> editor_reload_scene -> editor_lifecycle_wait
-> editor_get_context -> terrain_get_scene_summary

For a newly created test scene, save both layers:

text
editor_create_scene(preview=true)
-> editor_create_scene -> editor_lifecycle_wait
-> terrain_save_scene? -> data_save or data_save_and_generate

terrain_save_scene persists loaded terrain content and projection. data_save persists the DataManager scene index. Do not omit data_save when the scene must survive project reload or be formally deleted later.

Undo/Redo safety ​

Read history_state_id from terrain_get_state and pass it as expected_state_id to terrain_undo / terrain_redo. If the state is stale, re-read state and stop using the old command. Use terrain_list_history to verify one transaction per Apply and to inspect operation types.

Lifecycle and cleanup ​

Use the Editor lifecycle Skill for project/scene operations:

text
editor_get_context
-> editor_create_scene(preview=true)
-> editor_create_scene -> editor_lifecycle_wait
-> edits and explicit saves
-> editor_reload_scene / editor_reload_project
-> editor_open_scene(existing_scene)
-> editor_delete_scene(preview=true)
-> editor_delete_scene(confirm=true) -> editor_lifecycle_wait
-> editor_get_context + terrain_list_scenes

Deletion requires Preview then confirmation. Never delete the current scene or default. Resolve unsaved_changes explicitly with save or discard, then repeat the delete Preview.

Error handling ​

ErrorResponse
terrain_map_not_loadedOpen the required project and scene.
terrain_height_topology_unsupportedRead unsupported tiles; change region/height or stop.
terrain_height_tile_thickness_inconsistentSplit the operation by compatible TileSet thickness.
terrain_path_mixed_tile_setSplit the ramp operation by owning TileSet.
terrain_water_path_conflictWater overlaps ramp topology; change the region or explicitly erase the ramp first.
terrain_history_state_staleRe-read state and preview again.
editor_busyWait for the active lifecycle operation.
unsaved_changesUse explicit save/discard/cancel; repeat destructive Preview.
scene_not_found / invalid_scene_pathRe-list scenes and use a safe one-level scene name.

Evidence requirements ​

When reporting a completed workflow, include:

  • Editor project and scene from editor_get_context;
  • backend capability and TileSet diagnostics;
  • Preview and Apply result/error codes;
  • history state or operation type;
  • explicit save result and terrain_validate_scene output;
  • reload/reopen result;
  • for test scenes, DataManager save and post-delete index/directory checks.

Do not claim complete Runtime terrain observability based only on a successful visual screenshot. Use Editor-side structured Terrain validation for the authoring result.