主题
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=1means 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
TileThicknessis rejected withterrain_height_tile_thickness_inconsistent; split the edit by compatible thickness. - Core authoring is Preview/Early Access ready. Runtime
terrain.snapshotexposes an explicit partial-observation contract: inspectobservation.unsupported_fields,observation.incomplete_fields,sampling,tile_sets,water, androadsbefore interpreting empty values.tile_sets.status=catalog_availableexposes the loaded TileSet/style catalog. Whentile_sets.distribution_status=available,tile_sets.distributionreports runtime tile-style counts, TileSet mapping, andmap_size_tiles; an empty or unreadable runtime map is reported asno_data. Detailed water/road topology remains unsupported at runtime; water presence is only a texture-label inference when available.
Preconditions
- Connect to the full Editor MCP, not standalone
TriggerMcpHost. - Call
editor_get_context. - If needed, use
editor_open_projectoreditor_open_scene, theneditor_lifecycle_wait. - Confirm
editor_get_context.ready_state == "scene_ready". - Call
terrain_get_scene_summary,terrain_get_state, and usuallyterrain_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/reloadCarry 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_paintUse terrain_list_tile_sets before TileSet changes. For a whole-tile switch:
text
terrain_preview_tile_set_paint -> terrain_apply_tile_set_paintDo 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_editFor 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_editWater 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_editfor 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_scatterwith 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_summaryFor 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_generateterrain_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_scenesDeletion 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
| Error | Response |
|---|---|
terrain_map_not_loaded | Open the required project and scene. |
terrain_height_topology_unsupported | Read unsupported tiles; change region/height or stop. |
terrain_height_tile_thickness_inconsistent | Split the operation by compatible TileSet thickness. |
terrain_path_mixed_tile_set | Split the ramp operation by owning TileSet. |
terrain_water_path_conflict | Water overlaps ramp topology; change the region or explicitly erase the ramp first. |
terrain_history_state_stale | Re-read state and preview again. |
editor_busy | Wait for the active lifecycle operation. |
unsaved_changes | Use explicit save/discard/cancel; repeat destructive Preview. |
scene_not_found / invalid_scene_path | Re-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_sceneoutput; - 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.